fix(variable_replace_visitor): do not skip boolean value (#9021)

This commit is contained in:
Srikanth Chekuri 2025-09-07 14:10:11 +05:30 committed by GitHub
parent 0f5825a2b3
commit 1d3a8ecd66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 66 additions and 11 deletions

View File

@ -444,11 +444,14 @@ func (v *variableReplacementVisitor) VisitValue(ctx *grammar.ValueContext) any {
// First get the original value
var originalValue string
if ctx.QUOTED_TEXT() != nil {
originalValue = ctx.QUOTED_TEXT().GetText()
quotedText := ctx.QUOTED_TEXT().GetText()
originalValue = trimQuotes(quotedText)
} else if ctx.NUMBER() != nil {
originalValue = ctx.NUMBER().GetText()
} else if ctx.KEY() != nil {
originalValue = ctx.KEY().GetText()
} else if ctx.BOOL() != nil {
originalValue = ctx.BOOL().GetText()
}
// Check if this is a variable (starts with $)
@ -477,6 +480,10 @@ func (v *variableReplacementVisitor) VisitValue(ctx *grammar.ValueContext) any {
}
// Return original value if not a variable or variable not found
// If it was quoted text and not a variable, return with quotes
if ctx.QUOTED_TEXT() != nil && !strings.HasPrefix(originalValue, "$") {
return ctx.QUOTED_TEXT().GetText()
}
return originalValue
}
@ -515,13 +522,19 @@ func (v *variableReplacementVisitor) formatVariableValue(value any) string {
case string:
// Quote string values
return fmt.Sprintf("'%s'", strings.ReplaceAll(val, "'", "\\'"))
case []string:
parts := make([]string, len(val))
for i, item := range val {
parts[i] = fmt.Sprintf("'%s'", strings.ReplaceAll(item, "'", "\\'"))
}
return "[" + strings.Join(parts, ", ") + "]"
case []any:
// Format array values
parts := make([]string, len(val))
for i, item := range val {
parts[i] = v.formatVariableValue(item)
}
return "(" + strings.Join(parts, ", ") + ")"
return "[" + strings.Join(parts, ", ") + "]"
case int, int32, int64, float32, float64:
return fmt.Sprintf("%v", val)
case bool:
@ -530,3 +543,12 @@ func (v *variableReplacementVisitor) formatVariableValue(value any) string {
return fmt.Sprintf("%v", val)
}
}
func trimQuotes(s string) string {
if len(s) >= 2 {
if (s[0] == '"' && s[len(s)-1] == '"') || (s[0] == '\'' && s[len(s)-1] == '\'') {
return s[1 : len(s)-1]
}
}
return s
}

View File

@ -26,6 +26,39 @@ func TestReplaceVariablesInExpression(t *testing.T) {
},
expected: "service.name = 'auth-service'",
},
{
name: "simple bool check",
expression: "has_error = true",
variables: map[string]qbtypes.VariableItem{
"service": {
Type: qbtypes.DynamicVariableType,
Value: "auth-service",
},
},
expected: "has_error = true",
},
{
name: "variable inside quotes",
expression: "service.name ='$service'",
variables: map[string]qbtypes.VariableItem{
"service": {
Type: qbtypes.DynamicVariableType,
Value: "auth-service",
},
},
expected: "service.name = 'auth-service'",
},
{
name: "IN clause with variable inside quotes",
expression: "service.name IN '$service'",
variables: map[string]qbtypes.VariableItem{
"service": {
Type: qbtypes.DynamicVariableType,
Value: []string{"auth-service"},
},
},
expected: "service.name IN ['auth-service']",
},
{
name: "simple string variable replacement",
expression: "service.name = $service",
@ -101,7 +134,7 @@ func TestReplaceVariablesInExpression(t *testing.T) {
Value: []any{"auth", "api", "web"},
},
},
expected: "service.name IN ('auth', 'api', 'web')",
expected: "service.name IN ['auth', 'api', 'web']",
},
{
name: "array variable with mixed types",
@ -112,7 +145,7 @@ func TestReplaceVariablesInExpression(t *testing.T) {
Value: []any{1, 2, "three", 4.5},
},
},
expected: "id IN (1, 2, 'three', 4.5)",
expected: "id IN [1, 2, 'three', 4.5]",
},
{
name: "multiple variables in expression",
@ -185,7 +218,7 @@ func TestReplaceVariablesInExpression(t *testing.T) {
Value: []any{"test", "debug"},
},
},
expected: "service.name NOT IN ('test', 'debug')",
expected: "service.name NOT IN ['test', 'debug']",
},
{
name: "variable in BETWEEN clause",
@ -233,7 +266,7 @@ func TestReplaceVariablesInExpression(t *testing.T) {
Value: []any{"error", "warning", "info"},
},
},
expected: "hasAny(tags, ('error', 'warning', 'info'))",
expected: "hasAny(tags, ['error', 'warning', 'info'])",
},
{
name: "variable in hasToken function",
@ -255,7 +288,7 @@ func TestReplaceVariablesInExpression(t *testing.T) {
Value: []any{},
},
},
expected: "service.name IN ()",
expected: "service.name IN []",
},
{
name: "expression with OR and variables",
@ -306,7 +339,7 @@ func TestReplaceVariablesInExpression(t *testing.T) {
Value: 500,
},
},
expected: "(service.name IN ('auth', 'api') AND env = 'prod') OR (status_code >= 500)",
expected: "(service.name IN ['auth', 'api'] AND env = 'prod') OR (status_code >= 500)",
},
{
name: "float variable",
@ -446,17 +479,17 @@ func TestFormatVariableValue(t *testing.T) {
{
name: "array of strings",
value: []any{"a", "b", "c"},
expected: "('a', 'b', 'c')",
expected: "['a', 'b', 'c']",
},
{
name: "array of mixed types",
value: []any{"string", 123, true, 45.6},
expected: "('string', 123, true, 45.6)",
expected: "['string', 123, true, 45.6]",
},
{
name: "empty array",
value: []any{},
expected: "()",
expected: "[]",
},
{
name: "nil value",