mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-18 07:56:56 +00:00
feat: add support for negation context in query processing
This commit is contained in:
parent
6f08aff58b
commit
c783c5c7ee
@ -248,9 +248,9 @@ export function findKeyOperatorValueTriplet(
|
|||||||
FilterQueryLexer.GT,
|
FilterQueryLexer.GT,
|
||||||
FilterQueryLexer.GE,
|
FilterQueryLexer.GE,
|
||||||
FilterQueryLexer.LIKE,
|
FilterQueryLexer.LIKE,
|
||||||
FilterQueryLexer.NOT_LIKE,
|
// FilterQueryLexer.NOT_LIKE,
|
||||||
FilterQueryLexer.ILIKE,
|
FilterQueryLexer.ILIKE,
|
||||||
FilterQueryLexer.NOT_ILIKE,
|
// FilterQueryLexer.NOT_ILIKE,
|
||||||
FilterQueryLexer.BETWEEN,
|
FilterQueryLexer.BETWEEN,
|
||||||
FilterQueryLexer.EXISTS,
|
FilterQueryLexer.EXISTS,
|
||||||
FilterQueryLexer.REGEXP,
|
FilterQueryLexer.REGEXP,
|
||||||
@ -375,6 +375,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: true, // Default to key context when input is empty
|
isInKey: true, // Default to key context when input is empty
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -388,6 +389,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: cursorIndex,
|
stop: cursorIndex,
|
||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
|
isInNegation: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -418,6 +420,8 @@ export function getQueryContextAtCursor(
|
|||||||
|
|
||||||
const isInKey = currentToken.type === FilterQueryLexer.KEY;
|
const isInKey = currentToken.type === FilterQueryLexer.KEY;
|
||||||
|
|
||||||
|
const isInNegation = currentToken.type === FilterQueryLexer.NOT;
|
||||||
|
|
||||||
const isInOperator = [
|
const isInOperator = [
|
||||||
FilterQueryLexer.EQUALS,
|
FilterQueryLexer.EQUALS,
|
||||||
FilterQueryLexer.NOT_EQUALS,
|
FilterQueryLexer.NOT_EQUALS,
|
||||||
@ -427,9 +431,9 @@ export function getQueryContextAtCursor(
|
|||||||
FilterQueryLexer.GT,
|
FilterQueryLexer.GT,
|
||||||
FilterQueryLexer.GE,
|
FilterQueryLexer.GE,
|
||||||
FilterQueryLexer.LIKE,
|
FilterQueryLexer.LIKE,
|
||||||
FilterQueryLexer.NOT_LIKE,
|
// FilterQueryLexer.NOT_LIKE,
|
||||||
FilterQueryLexer.ILIKE,
|
FilterQueryLexer.ILIKE,
|
||||||
FilterQueryLexer.NOT_ILIKE,
|
// FilterQueryLexer.NOT_ILIKE,
|
||||||
FilterQueryLexer.BETWEEN,
|
FilterQueryLexer.BETWEEN,
|
||||||
FilterQueryLexer.EXISTS,
|
FilterQueryLexer.EXISTS,
|
||||||
FilterQueryLexer.REGEXP,
|
FilterQueryLexer.REGEXP,
|
||||||
@ -442,7 +446,7 @@ export function getQueryContextAtCursor(
|
|||||||
FilterQueryLexer.HAS,
|
FilterQueryLexer.HAS,
|
||||||
FilterQueryLexer.HASANY,
|
FilterQueryLexer.HASANY,
|
||||||
FilterQueryLexer.HASALL,
|
FilterQueryLexer.HASALL,
|
||||||
FilterQueryLexer.HASNONE,
|
// FilterQueryLexer.HASNONE,
|
||||||
].includes(currentToken.type);
|
].includes(currentToken.type);
|
||||||
|
|
||||||
// Get the context-related tokens (key, operator, value)
|
// Get the context-related tokens (key, operator, value)
|
||||||
@ -473,6 +477,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: true,
|
isInOperator: true,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -491,6 +496,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: true,
|
isInValue: true,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -509,6 +515,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: true,
|
isInConjunction: true,
|
||||||
@ -526,6 +533,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: currentToken.stop,
|
stop: currentToken.stop,
|
||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
|
isInNegation: false,
|
||||||
isInKey: true,
|
isInKey: true,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -546,6 +554,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: currentToken.stop,
|
stop: currentToken.stop,
|
||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
|
isInNegation: false,
|
||||||
isInKey: true,
|
isInKey: true,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -567,6 +576,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: currentToken.stop,
|
stop: currentToken.stop,
|
||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
|
isInNegation: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -585,6 +595,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: currentToken.stop,
|
stop: currentToken.stop,
|
||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: true,
|
isInValue: true,
|
||||||
|
isInNegation: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -612,6 +623,25 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: true,
|
isInKey: true,
|
||||||
|
isInNegation: false,
|
||||||
|
isInOperator: false,
|
||||||
|
isInFunction: false,
|
||||||
|
isInConjunction: false,
|
||||||
|
isInParenthesis: false,
|
||||||
|
...relationTokens, // Include related tokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInNegation && nextToken.type === FilterQueryLexer.NOT) {
|
||||||
|
return {
|
||||||
|
tokenType: currentToken.type,
|
||||||
|
text: currentToken.text,
|
||||||
|
start: currentToken.start,
|
||||||
|
stop: currentToken.stop,
|
||||||
|
currentToken: currentToken.text,
|
||||||
|
isInValue: false,
|
||||||
|
isInKey: false,
|
||||||
|
isInNegation: true,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -636,6 +666,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: true,
|
isInOperator: true,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -660,6 +691,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: true,
|
isInValue: true,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -684,6 +716,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: true,
|
isInConjunction: true,
|
||||||
@ -703,6 +736,25 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: true,
|
isInKey: true,
|
||||||
|
isInNegation: false,
|
||||||
|
isInOperator: false,
|
||||||
|
isInFunction: false,
|
||||||
|
isInConjunction: false,
|
||||||
|
isInParenthesis: false,
|
||||||
|
...relationTokens, // Include related tokens
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextToken.type === FilterQueryLexer.NOT) {
|
||||||
|
return {
|
||||||
|
tokenType: -1,
|
||||||
|
text: '',
|
||||||
|
start: cursorIndex,
|
||||||
|
stop: cursorIndex,
|
||||||
|
currentToken: '',
|
||||||
|
isInValue: false,
|
||||||
|
isInKey: false,
|
||||||
|
isInNegation: true,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -729,6 +781,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: true,
|
isInOperator: true,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -750,6 +803,7 @@ export function getQueryContextAtCursor(
|
|||||||
start: cursorIndex,
|
start: cursorIndex,
|
||||||
stop: cursorIndex,
|
stop: cursorIndex,
|
||||||
currentToken: '',
|
currentToken: '',
|
||||||
|
isInNegation: false,
|
||||||
isInValue: true,
|
isInValue: true,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
@ -769,6 +823,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: true,
|
isInConjunction: true,
|
||||||
@ -794,6 +849,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -812,6 +868,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: currentToken.text,
|
currentToken: currentToken.text,
|
||||||
isInValue,
|
isInValue,
|
||||||
isInKey,
|
isInKey,
|
||||||
|
isInNegation,
|
||||||
isInOperator,
|
isInOperator,
|
||||||
isInFunction,
|
isInFunction,
|
||||||
isInConjunction,
|
isInConjunction,
|
||||||
@ -828,6 +885,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -836,6 +894,16 @@ export function getQueryContextAtCursor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const negationQueryOperatorSuggestions = [
|
||||||
|
{ label: 'LIKE', type: 'operator', info: 'Like' },
|
||||||
|
{ label: 'ILIKE', type: 'operator', info: 'Case insensitive like' },
|
||||||
|
{ label: 'EXISTS', type: 'operator', info: 'Exists' },
|
||||||
|
{ label: 'BETWEEN', type: 'operator', info: 'Between' },
|
||||||
|
{ label: 'IN', type: 'operator', info: 'In' },
|
||||||
|
{ label: 'REGEXP', type: 'operator', info: 'Regular expression' },
|
||||||
|
{ label: 'CONTAINS', type: 'operator', info: 'Contains' },
|
||||||
|
];
|
||||||
|
|
||||||
export const queryOperatorSuggestions = [
|
export const queryOperatorSuggestions = [
|
||||||
{ label: '=', type: 'operator', info: 'Equal to' },
|
{ label: '=', type: 'operator', info: 'Equal to' },
|
||||||
{ label: '!=', type: 'operator', info: 'Not equal to' },
|
{ label: '!=', type: 'operator', info: 'Not equal to' },
|
||||||
@ -843,14 +911,6 @@ export const queryOperatorSuggestions = [
|
|||||||
{ label: '<', type: 'operator', info: 'Less than' },
|
{ label: '<', type: 'operator', info: 'Less than' },
|
||||||
{ label: '>=', type: 'operator', info: 'Greater than or equal to' },
|
{ label: '>=', type: 'operator', info: 'Greater than or equal to' },
|
||||||
{ label: '<=', type: 'operator', info: 'Less than or equal to' },
|
{ label: '<=', type: 'operator', info: 'Less than or equal to' },
|
||||||
{ label: 'LIKE', type: 'operator', info: 'Like' },
|
|
||||||
{ label: 'ILIKE', type: 'operator', info: 'Case insensitive like' },
|
|
||||||
{ label: 'BETWEEN', type: 'operator', info: 'Between' },
|
|
||||||
{ label: 'EXISTS', type: 'operator', info: 'Exists' },
|
|
||||||
{ label: 'NOT_EXISTS', type: 'operator', info: 'Not Exists' },
|
|
||||||
{ label: 'REGEXP', type: 'operator', info: 'Regular expression' },
|
|
||||||
{ label: 'CONTAINS', type: 'operator', info: 'Contains' },
|
|
||||||
{ label: 'IN', type: 'operator', info: 'In' },
|
|
||||||
{ label: 'NOT', type: 'operator', info: 'Not' },
|
{ label: 'NOT', type: 'operator', info: 'Not' },
|
||||||
{ label: 'NOT_LIKE', type: 'operator', info: 'Not like' },
|
...negationQueryOperatorSuggestions,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -51,6 +51,7 @@ function normalizeSpaces(query: string): string {
|
|||||||
export function createContext(
|
export function createContext(
|
||||||
token: Token,
|
token: Token,
|
||||||
isInKey: boolean,
|
isInKey: boolean,
|
||||||
|
isInNegation: boolean,
|
||||||
isInOperator: boolean,
|
isInOperator: boolean,
|
||||||
isInValue: boolean,
|
isInValue: boolean,
|
||||||
keyToken?: string,
|
keyToken?: string,
|
||||||
@ -66,6 +67,7 @@ export function createContext(
|
|||||||
stop: token.stop,
|
stop: token.stop,
|
||||||
currentToken: token.text || '',
|
currentToken: token.text || '',
|
||||||
isInKey,
|
isInKey,
|
||||||
|
isInNegation,
|
||||||
isInOperator,
|
isInOperator,
|
||||||
isInValue,
|
isInValue,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -85,6 +87,7 @@ function determineTokenContext(
|
|||||||
query: string,
|
query: string,
|
||||||
): {
|
): {
|
||||||
isInKey: boolean;
|
isInKey: boolean;
|
||||||
|
isInNegation: boolean;
|
||||||
isInOperator: boolean;
|
isInOperator: boolean;
|
||||||
isInValue: boolean;
|
isInValue: boolean;
|
||||||
isInFunction: boolean;
|
isInFunction: boolean;
|
||||||
@ -92,6 +95,7 @@ function determineTokenContext(
|
|||||||
isInParenthesis: boolean;
|
isInParenthesis: boolean;
|
||||||
} {
|
} {
|
||||||
let isInKey: boolean = false;
|
let isInKey: boolean = false;
|
||||||
|
let isInNegation: boolean = false;
|
||||||
let isInOperator: boolean = false;
|
let isInOperator: boolean = false;
|
||||||
let isInValue: boolean = false;
|
let isInValue: boolean = false;
|
||||||
let isInFunction: boolean = false;
|
let isInFunction: boolean = false;
|
||||||
@ -126,6 +130,9 @@ function determineTokenContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Negation context
|
||||||
|
isInNegation = tokenType === FilterQueryLexer.NOT;
|
||||||
|
|
||||||
// Function context
|
// Function context
|
||||||
isInFunction = isFunctionToken(tokenType);
|
isInFunction = isFunctionToken(tokenType);
|
||||||
|
|
||||||
@ -137,6 +144,7 @@ function determineTokenContext(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
isInKey,
|
isInKey,
|
||||||
|
isInNegation,
|
||||||
isInOperator,
|
isInOperator,
|
||||||
isInValue,
|
isInValue,
|
||||||
isInFunction,
|
isInFunction,
|
||||||
@ -156,6 +164,7 @@ function determineContextBoundaries(
|
|||||||
operatorContext: { start: number; end: number } | null;
|
operatorContext: { start: number; end: number } | null;
|
||||||
valueContext: { start: number; end: number } | null;
|
valueContext: { start: number; end: number } | null;
|
||||||
conjunctionContext: { start: number; end: number } | null;
|
conjunctionContext: { start: number; end: number } | null;
|
||||||
|
negationContext: { start: number; end: number } | null;
|
||||||
bracketContext: { start: number; end: number; isForList: boolean } | null;
|
bracketContext: { start: number; end: number; isForList: boolean } | null;
|
||||||
} {
|
} {
|
||||||
// Find the current query pair based on cursor position
|
// Find the current query pair based on cursor position
|
||||||
@ -343,6 +352,12 @@ function determineContextBoundaries(
|
|||||||
if (currentPair) {
|
if (currentPair) {
|
||||||
const { position } = currentPair;
|
const { position } = currentPair;
|
||||||
|
|
||||||
|
// Negation context: from negationStart to negationEnd
|
||||||
|
const negationContext = {
|
||||||
|
start: position.negationStart ?? 0,
|
||||||
|
end: position.negationEnd ?? 0,
|
||||||
|
};
|
||||||
|
|
||||||
// Key context: from keyStart to keyEnd
|
// Key context: from keyStart to keyEnd
|
||||||
const keyContext = {
|
const keyContext = {
|
||||||
start: position.keyStart,
|
start: position.keyStart,
|
||||||
@ -412,6 +427,7 @@ function determineContextBoundaries(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
keyContext,
|
keyContext,
|
||||||
|
negationContext,
|
||||||
operatorContext,
|
operatorContext,
|
||||||
valueContext,
|
valueContext,
|
||||||
conjunctionContext,
|
conjunctionContext,
|
||||||
@ -433,6 +449,18 @@ function determineContextBoundaries(
|
|||||||
if (tokenAtCursor.type === FilterQueryLexer.KEY) {
|
if (tokenAtCursor.type === FilterQueryLexer.KEY) {
|
||||||
return {
|
return {
|
||||||
keyContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
keyContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
||||||
|
negationContext: null,
|
||||||
|
operatorContext: null,
|
||||||
|
valueContext: null,
|
||||||
|
conjunctionContext: null,
|
||||||
|
bracketContext,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenAtCursor.type === FilterQueryLexer.NOT) {
|
||||||
|
return {
|
||||||
|
keyContext: null,
|
||||||
|
negationContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
||||||
operatorContext: null,
|
operatorContext: null,
|
||||||
valueContext: null,
|
valueContext: null,
|
||||||
conjunctionContext: null,
|
conjunctionContext: null,
|
||||||
@ -443,6 +471,7 @@ function determineContextBoundaries(
|
|||||||
if (isOperatorToken(tokenAtCursor.type)) {
|
if (isOperatorToken(tokenAtCursor.type)) {
|
||||||
return {
|
return {
|
||||||
keyContext: null,
|
keyContext: null,
|
||||||
|
negationContext: null,
|
||||||
operatorContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
operatorContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
||||||
valueContext: null,
|
valueContext: null,
|
||||||
conjunctionContext: null,
|
conjunctionContext: null,
|
||||||
@ -453,6 +482,7 @@ function determineContextBoundaries(
|
|||||||
if (isValueToken(tokenAtCursor.type)) {
|
if (isValueToken(tokenAtCursor.type)) {
|
||||||
return {
|
return {
|
||||||
keyContext: null,
|
keyContext: null,
|
||||||
|
negationContext: null,
|
||||||
operatorContext: null,
|
operatorContext: null,
|
||||||
valueContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
valueContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
||||||
conjunctionContext: null,
|
conjunctionContext: null,
|
||||||
@ -463,6 +493,7 @@ function determineContextBoundaries(
|
|||||||
if (isConjunctionToken(tokenAtCursor.type)) {
|
if (isConjunctionToken(tokenAtCursor.type)) {
|
||||||
return {
|
return {
|
||||||
keyContext: null,
|
keyContext: null,
|
||||||
|
negationContext: null,
|
||||||
operatorContext: null,
|
operatorContext: null,
|
||||||
valueContext: null,
|
valueContext: null,
|
||||||
conjunctionContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
conjunctionContext: { start: tokenAtCursor.start, end: tokenAtCursor.stop },
|
||||||
@ -474,6 +505,7 @@ function determineContextBoundaries(
|
|||||||
// If no current pair, return null for all contexts except possibly bracket context
|
// If no current pair, return null for all contexts except possibly bracket context
|
||||||
return {
|
return {
|
||||||
keyContext: null,
|
keyContext: null,
|
||||||
|
negationContext: null,
|
||||||
operatorContext: null,
|
operatorContext: null,
|
||||||
valueContext: null,
|
valueContext: null,
|
||||||
conjunctionContext: null,
|
conjunctionContext: null,
|
||||||
@ -515,6 +547,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: cursorIndex,
|
stop: cursorIndex,
|
||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInKey: true,
|
isInKey: true,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -660,6 +693,12 @@ export function getQueryContextAtCursor(
|
|||||||
adjustedCursorIndex <= contextBoundaries.keyContext.end) ||
|
adjustedCursorIndex <= contextBoundaries.keyContext.end) ||
|
||||||
adjustedCursorIndex === contextBoundaries.keyContext.end + 1);
|
adjustedCursorIndex === contextBoundaries.keyContext.end + 1);
|
||||||
|
|
||||||
|
const isInNegationBoundary =
|
||||||
|
contextBoundaries.negationContext &&
|
||||||
|
((adjustedCursorIndex >= contextBoundaries.negationContext.start &&
|
||||||
|
adjustedCursorIndex <= contextBoundaries.negationContext.end) ||
|
||||||
|
adjustedCursorIndex === contextBoundaries.negationContext.end + 1);
|
||||||
|
|
||||||
const isInOperatorBoundary =
|
const isInOperatorBoundary =
|
||||||
contextBoundaries.operatorContext &&
|
contextBoundaries.operatorContext &&
|
||||||
((adjustedCursorIndex >= contextBoundaries.operatorContext.start &&
|
((adjustedCursorIndex >= contextBoundaries.operatorContext.start &&
|
||||||
@ -703,6 +742,7 @@ export function getQueryContextAtCursor(
|
|||||||
// If cursor is within a specific context boundary, this takes precedence
|
// If cursor is within a specific context boundary, this takes precedence
|
||||||
if (
|
if (
|
||||||
isInKeyBoundary ||
|
isInKeyBoundary ||
|
||||||
|
isInNegationBoundary ||
|
||||||
isInOperatorBoundary ||
|
isInOperatorBoundary ||
|
||||||
isInValueBoundary ||
|
isInValueBoundary ||
|
||||||
isInConjunctionBoundary ||
|
isInConjunctionBoundary ||
|
||||||
@ -736,6 +776,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInKey: isInKeyBoundary || false,
|
isInKey: isInKeyBoundary || false,
|
||||||
|
isInNegation: isInNegationBoundary || false,
|
||||||
isInOperator: isInOperatorBoundary || false,
|
isInOperator: isInOperatorBoundary || false,
|
||||||
isInValue: finalIsInValue || false,
|
isInValue: finalIsInValue || false,
|
||||||
isInConjunction: finalIsInConjunction || false,
|
isInConjunction: finalIsInConjunction || false,
|
||||||
@ -824,6 +865,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInKey: true, // Default to key context when input is empty
|
isInKey: true, // Default to key context when input is empty
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -853,6 +895,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: lastTokenBeforeCursor.text,
|
currentToken: lastTokenBeforeCursor.text,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: true, // After key + space, should be operator context
|
isInOperator: true, // After key + space, should be operator context
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -865,6 +908,27 @@ export function getQueryContextAtCursor(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastTokenContext.isInNegation) {
|
||||||
|
return {
|
||||||
|
tokenType: lastTokenBeforeCursor.type,
|
||||||
|
text: lastTokenBeforeCursor.text,
|
||||||
|
start: adjustedCursorIndex,
|
||||||
|
stop: adjustedCursorIndex,
|
||||||
|
currentToken: lastTokenBeforeCursor.text,
|
||||||
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
|
isInOperator: true, // After key + space + NOT, should be operator context
|
||||||
|
isInValue: false,
|
||||||
|
isInFunction: false,
|
||||||
|
isInConjunction: false,
|
||||||
|
isInParenthesis: false,
|
||||||
|
isInBracketList: false,
|
||||||
|
keyToken: lastTokenBeforeCursor.text,
|
||||||
|
queryPairs: queryPairs,
|
||||||
|
currentPair: currentPair,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (lastTokenContext.isInOperator) {
|
if (lastTokenContext.isInOperator) {
|
||||||
// If we just typed an operator and then a space, we move to value context
|
// If we just typed an operator and then a space, we move to value context
|
||||||
const keyFromPair = currentPair?.key || '';
|
const keyFromPair = currentPair?.key || '';
|
||||||
@ -876,6 +940,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: lastTokenBeforeCursor.text,
|
currentToken: lastTokenBeforeCursor.text,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: !isNonValueToken, // After operator + space, should be value context
|
isInValue: !isNonValueToken, // After operator + space, should be value context
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -900,6 +965,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: lastTokenBeforeCursor.text,
|
currentToken: lastTokenBeforeCursor.text,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -923,6 +989,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: lastTokenBeforeCursor.text,
|
currentToken: lastTokenBeforeCursor.text,
|
||||||
isInKey: true, // After conjunction + space, should be key context
|
isInKey: true, // After conjunction + space, should be key context
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -1016,6 +1083,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: previousToken.text,
|
currentToken: previousToken.text,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: true, // Always in value context after operator
|
isInValue: true, // Always in value context after operator
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -1038,6 +1106,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: previousToken.text,
|
currentToken: previousToken.text,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: true, // After key, progress to operator context
|
isInOperator: true, // After key, progress to operator context
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -1058,6 +1127,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: previousToken.text,
|
currentToken: previousToken.text,
|
||||||
isInKey: false,
|
isInKey: false,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -1080,6 +1150,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: previousToken.text,
|
currentToken: previousToken.text,
|
||||||
isInKey: true, // After conjunction, progress back to key context
|
isInKey: true, // After conjunction, progress back to key context
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -1100,6 +1171,7 @@ export function getQueryContextAtCursor(
|
|||||||
stop: adjustedCursorIndex,
|
stop: adjustedCursorIndex,
|
||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInKey: true,
|
isInKey: true,
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
@ -1119,6 +1191,7 @@ export function getQueryContextAtCursor(
|
|||||||
currentToken: '',
|
currentToken: '',
|
||||||
isInValue: false,
|
isInValue: false,
|
||||||
isInKey: true, // Default to key context on error
|
isInKey: true, // Default to key context on error
|
||||||
|
isInNegation: false,
|
||||||
isInOperator: false,
|
isInOperator: false,
|
||||||
isInFunction: false,
|
isInFunction: false,
|
||||||
isInConjunction: false,
|
isInConjunction: false,
|
||||||
@ -1185,6 +1258,7 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
key: currentPair.key,
|
key: currentPair.key,
|
||||||
operator: currentPair.operator || '',
|
operator: currentPair.operator || '',
|
||||||
value: currentPair.value,
|
value: currentPair.value,
|
||||||
|
hasNegation: currentPair.hasNegation || false,
|
||||||
position: {
|
position: {
|
||||||
keyStart: currentPair.position?.keyStart || 0,
|
keyStart: currentPair.position?.keyStart || 0,
|
||||||
keyEnd: currentPair.position?.keyEnd || 0,
|
keyEnd: currentPair.position?.keyEnd || 0,
|
||||||
@ -1192,6 +1266,8 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
operatorEnd: currentPair.position?.operatorEnd || 0,
|
operatorEnd: currentPair.position?.operatorEnd || 0,
|
||||||
valueStart: currentPair.position?.valueStart,
|
valueStart: currentPair.position?.valueStart,
|
||||||
valueEnd: currentPair.position?.valueEnd,
|
valueEnd: currentPair.position?.valueEnd,
|
||||||
|
negationStart: currentPair.position?.negationStart || 0,
|
||||||
|
negationEnd: currentPair.position?.negationEnd || 0,
|
||||||
},
|
},
|
||||||
isComplete: !!(
|
isComplete: !!(
|
||||||
currentPair.key &&
|
currentPair.key &&
|
||||||
@ -1212,6 +1288,22 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// If NOT token comes set hasNegation to true
|
||||||
|
else if (token.type === FilterQueryLexer.NOT && currentPair) {
|
||||||
|
currentPair.hasNegation = true;
|
||||||
|
|
||||||
|
currentPair.position = {
|
||||||
|
keyStart: currentPair.position?.keyStart || 0,
|
||||||
|
keyEnd: currentPair.position?.keyEnd || 0,
|
||||||
|
operatorStart: currentPair.position?.operatorStart || 0,
|
||||||
|
operatorEnd: currentPair.position?.operatorEnd || 0,
|
||||||
|
valueStart: currentPair.position?.valueStart,
|
||||||
|
valueEnd: currentPair.position?.valueEnd,
|
||||||
|
negationStart: token.start,
|
||||||
|
negationEnd: token.stop,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// If token is an operator and we have a key, add the operator
|
// If token is an operator and we have a key, add the operator
|
||||||
else if (
|
else if (
|
||||||
isOperatorToken(token.type) &&
|
isOperatorToken(token.type) &&
|
||||||
@ -1228,6 +1320,8 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
operatorEnd: token.stop,
|
operatorEnd: token.stop,
|
||||||
valueStart: currentPair.position?.valueStart,
|
valueStart: currentPair.position?.valueStart,
|
||||||
valueEnd: currentPair.position?.valueEnd,
|
valueEnd: currentPair.position?.valueEnd,
|
||||||
|
negationStart: currentPair.position?.negationStart || 0,
|
||||||
|
negationEnd: currentPair.position?.negationEnd || 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// If token is a value and we have a key and operator, add the value
|
// If token is a value and we have a key and operator, add the value
|
||||||
@ -1247,6 +1341,8 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
operatorEnd: currentPair.position?.operatorEnd || 0,
|
operatorEnd: currentPair.position?.operatorEnd || 0,
|
||||||
valueStart: token.start,
|
valueStart: token.start,
|
||||||
valueEnd: token.stop,
|
valueEnd: token.stop,
|
||||||
|
negationStart: currentPair.position?.negationStart || 0,
|
||||||
|
negationEnd: currentPair.position?.negationEnd || 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// If token is a conjunction (AND/OR), finalize the current pair
|
// If token is a conjunction (AND/OR), finalize the current pair
|
||||||
@ -1255,6 +1351,7 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
key: currentPair.key,
|
key: currentPair.key,
|
||||||
operator: currentPair.operator || '',
|
operator: currentPair.operator || '',
|
||||||
value: currentPair.value,
|
value: currentPair.value,
|
||||||
|
hasNegation: currentPair.hasNegation || false,
|
||||||
position: {
|
position: {
|
||||||
keyStart: currentPair.position?.keyStart || 0,
|
keyStart: currentPair.position?.keyStart || 0,
|
||||||
keyEnd: currentPair.position?.keyEnd || 0,
|
keyEnd: currentPair.position?.keyEnd || 0,
|
||||||
@ -1262,6 +1359,8 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
operatorEnd: currentPair.position?.operatorEnd || 0,
|
operatorEnd: currentPair.position?.operatorEnd || 0,
|
||||||
valueStart: currentPair.position?.valueStart,
|
valueStart: currentPair.position?.valueStart,
|
||||||
valueEnd: currentPair.position?.valueEnd,
|
valueEnd: currentPair.position?.valueEnd,
|
||||||
|
negationStart: currentPair.position?.negationStart || 0,
|
||||||
|
negationEnd: currentPair.position?.negationEnd || 0,
|
||||||
},
|
},
|
||||||
isComplete: !!(
|
isComplete: !!(
|
||||||
currentPair.key &&
|
currentPair.key &&
|
||||||
@ -1281,6 +1380,7 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
key: currentPair.key,
|
key: currentPair.key,
|
||||||
operator: currentPair.operator || '',
|
operator: currentPair.operator || '',
|
||||||
value: currentPair.value,
|
value: currentPair.value,
|
||||||
|
hasNegation: currentPair.hasNegation || false,
|
||||||
position: {
|
position: {
|
||||||
keyStart: currentPair.position?.keyStart || 0,
|
keyStart: currentPair.position?.keyStart || 0,
|
||||||
keyEnd: currentPair.position?.keyEnd || 0,
|
keyEnd: currentPair.position?.keyEnd || 0,
|
||||||
@ -1288,6 +1388,8 @@ export function extractQueryPairs(query: string): IQueryPair[] {
|
|||||||
operatorEnd: currentPair.position?.operatorEnd || 0,
|
operatorEnd: currentPair.position?.operatorEnd || 0,
|
||||||
valueStart: currentPair.position?.valueStart,
|
valueStart: currentPair.position?.valueStart,
|
||||||
valueEnd: currentPair.position?.valueEnd,
|
valueEnd: currentPair.position?.valueEnd,
|
||||||
|
negationStart: currentPair.position?.negationStart || 0,
|
||||||
|
negationEnd: currentPair.position?.negationEnd || 0,
|
||||||
},
|
},
|
||||||
isComplete: !!(
|
isComplete: !!(
|
||||||
currentPair.key &&
|
currentPair.key &&
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user