Fixed blank params on funcspec

This commit is contained in:
Hein 2025-12-03 11:42:32 +02:00
parent 81b87af6e4
commit 5ff9a8a24e
2 changed files with 100 additions and 4 deletions

View File

@ -163,8 +163,9 @@ func (h *Handler) SqlQueryList(sqlquery string, pNoCount, pBlankparms, pAllowFil
// Remove unused input variables
if pBlankparms {
for _, kw := range inputvars {
sqlquery = strings.ReplaceAll(sqlquery, kw, "")
logger.Debug("Removed unused variable: %s", kw)
replacement := getReplacementForBlankParam(sqlquery, kw)
sqlquery = strings.ReplaceAll(sqlquery, kw, replacement)
logger.Debug("Replaced unused variable %s with: %s", kw, replacement)
}
}
@ -501,8 +502,9 @@ func (h *Handler) SqlQuery(sqlquery string, pBlankparms bool) HTTPFuncType {
// Remove unused input variables
if pBlankparms {
for _, kw := range inputvars {
sqlquery = strings.ReplaceAll(sqlquery, kw, "")
logger.Debug("Removed unused variable: %s", kw)
replacement := getReplacementForBlankParam(sqlquery, kw)
sqlquery = strings.ReplaceAll(sqlquery, kw, replacement)
logger.Debug("Replaced unused variable %s with: %s", kw, replacement)
}
}
@ -870,6 +872,38 @@ func IsNumeric(s string) bool {
return err == nil
}
// getReplacementForBlankParam determines the replacement value for an unused parameter
// based on whether it appears within quotes in the SQL query.
// It checks for PostgreSQL quotes: single quotes ('') and dollar quotes ($...$)
func getReplacementForBlankParam(sqlquery, param string) string {
// Find the parameter in the query
idx := strings.Index(sqlquery, param)
if idx < 0 {
return ""
}
// Check characters immediately before and after the parameter
var charBefore, charAfter byte
if idx > 0 {
charBefore = sqlquery[idx-1]
}
endIdx := idx + len(param)
if endIdx < len(sqlquery) {
charAfter = sqlquery[endIdx]
}
// Check if parameter is surrounded by quotes (single quote or dollar sign for PostgreSQL dollar-quoted strings)
if (charBefore == '\'' || charBefore == '$') && (charAfter == '\'' || charAfter == '$') {
// Parameter is in quotes, return empty string
return ""
}
// Parameter is not in quotes, return NULL
return "NULL"
}
// makeResultReceiver creates a slice of interface{} pointers for scanning SQL rows
// func makeResultReceiver(length int) []interface{} {
// result := make([]interface{}, length)

View File

@ -835,3 +835,65 @@ func TestReplaceMetaVariables(t *testing.T) {
})
}
}
// TestGetReplacementForBlankParam tests the blank parameter replacement logic
func TestGetReplacementForBlankParam(t *testing.T) {
tests := []struct {
name string
sqlQuery string
param string
expected string
}{
{
name: "Parameter in single quotes",
sqlQuery: "SELECT * FROM users WHERE name = '[username]'",
param: "[username]",
expected: "",
},
{
name: "Parameter in dollar quotes",
sqlQuery: "SELECT * FROM users WHERE data = $[jsondata]$",
param: "[jsondata]",
expected: "",
},
{
name: "Parameter not in quotes",
sqlQuery: "SELECT * FROM users WHERE id = [user_id]",
param: "[user_id]",
expected: "NULL",
},
{
name: "Parameter not in quotes with AND",
sqlQuery: "SELECT * FROM users WHERE id = [user_id] AND status = 1",
param: "[user_id]",
expected: "NULL",
},
{
name: "Parameter in mixed quote context - before quote",
sqlQuery: "SELECT * FROM users WHERE id = [user_id] AND name = 'test'",
param: "[user_id]",
expected: "NULL",
},
{
name: "Parameter in mixed quote context - in quotes",
sqlQuery: "SELECT * FROM users WHERE name = '[username]' AND id = 1",
param: "[username]",
expected: "",
},
{
name: "Parameter with dollar quote tag",
sqlQuery: "SELECT * FROM users WHERE body = $tag$[content]$tag$",
param: "[content]",
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := getReplacementForBlankParam(tt.sqlQuery, tt.param)
if result != tt.expected {
t.Errorf("Expected replacement '%s', got '%s' for query: %s", tt.expected, result, tt.sqlQuery)
}
})
}
}