Skip to content

Commit d6ba025

Browse files
committed
bump version to 0.2.2 and normalize where field names to lowercase for consistent SQL generation
1 parent eb713ee commit d6ba025

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

sqlquery.nimble

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Package
22

3-
version = "0.2.1"
3+
version = "0.2.2"
44
author = "ThomasTJdev"
55
description = "SQL query builder and validator - opiniated"
66
license = "MIT"

src/sqlquery/sql_query_core.nim

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,12 @@ proc compileValidateWhereField(
264264
allowCrossTable: bool,
265265
contextPrefix: string
266266
) =
267-
var fieldStr = fieldRaw
268-
if fieldStr.startsWith("sql:>"):
267+
if fieldRaw.startsWith("sql:>"):
269268
return
270269

270+
# Match parseWhereCondition: schema validation is case-insensitive; SQL uses lowercase identifiers.
271+
var fieldStr = fieldRaw.toLowerAscii().strip()
272+
271273
# Allow PostgreSQL functions in where clause similarly to runtime parser.
272274
if "(" in fieldStr:
273275
let s1 = fieldStr.split("(")[1]
@@ -387,13 +389,16 @@ proc extractColumnRefs(sqlExpr: string): seq[string] =
387389
return refs
388390

389391
proc parseWhereCondition(condition: WhereSpec, conditionIndex: int, requireTableName = true, table = "", validateSchema = true): tuple[statement: string, params: seq[string]] =
390-
var field = condition[0]
392+
let fieldRaw = condition[0]
393+
let customSQL = fieldRaw.startsWith("sql:>")
394+
# Non-custom fields are normalized like parseSelect so validation matches the schema and emitted SQL is stable.
395+
var field = if not customSQL: fieldRaw.toLowerAscii().strip() else: fieldRaw
396+
391397
if field == "project_id" and conditionIndex > 0:
392398
sqlWarning("project_id within a where statement will in 99% of cases be the first condition. That's our indexes!")
393399

394400
let symbol = condition[1]
395401
let value = condition[2]
396-
let customSQL = field.startsWith("sql:>")
397402
var skipRestValidation = false
398403

399404
if symbol.len() == 0 and value.len() == 0 and not customSQL:

tests/test_sqlquery_generator.nim

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,31 @@ suite "selectQuery":
283283
check base.sql == "SELECT actions.id, actions.name, actions.status FROM actions LEFT JOIN project as p ON p.id = actions.project_id WHERE actions.project_id = ? AND actions.is_deleted IS NULL GROUP BY p.name"
284284
check base.params == @["123"]
285285

286+
test "where field names are normalized to lowercase":
287+
let base = selectQuery(
288+
table = "actions",
289+
select = @["actions.id", "actions.name", "actions.status"],
290+
joins = @[("project AS p", LEFTJOIN, @[("p.id", "=", "actions.project_id")])],
291+
where = @[("Actions.PROJECT_ID", "=", "123")],
292+
groupBy = @["p.name"],
293+
)
294+
check base.sql == "SELECT actions.id, actions.name, actions.status FROM actions LEFT JOIN project as p ON p.id = actions.project_id WHERE actions.project_id = ? AND actions.is_deleted IS NULL GROUP BY p.name"
295+
check base.params == @["123"]
296+
297+
let grouped = selectQuery(
298+
table = "actions",
299+
select = @["actions.id"],
300+
where = whereAnd(@[
301+
whereCond("ACTIONS.Status", "=", "active"),
302+
whereOr(@[
303+
whereCond("Actions.NAME", "=", "thomas"),
304+
whereCond("actions.system", "=", "SYS"),
305+
]),
306+
]),
307+
)
308+
check grouped.sql == "SELECT actions.id FROM actions WHERE (actions.status = ? AND (actions.name = ? OR actions.system = ?)) AND actions.is_deleted IS NULL"
309+
check grouped.params == @["active", "thomas", "SYS"]
310+
286311
test "table with reserved word column name (method) using strings":
287312
# Test table with column named "method" which is a reserved word in Nim.
288313
# When using string literals, use the original SQL column name "method".
@@ -743,7 +768,7 @@ suite "WHERE operators extended":
743768
where = @[("actions.project_id", "=", "123"), ("LOWER(COALESCE(actions.name, ''))", "=", "test")]
744769
)
745770

746-
check query.sql == "SELECT actions.id, actions.name FROM actions WHERE actions.project_id = ? AND LOWER(COALESCE(actions.name, '')) = ? AND actions.is_deleted IS NULL"
771+
check query.sql == "SELECT actions.id, actions.name FROM actions WHERE actions.project_id = ? AND lower(coalesce(actions.name, '')) = ? AND actions.is_deleted IS NULL"
747772
check query.params == @["123", "test"]
748773

749774

0 commit comments

Comments
 (0)