refactor(exec): extract param binding into exec/params.nim

This commit is contained in:
2026-07-30 13:36:39 +03:00
parent 46e3d7f51e
commit 2efcddba19
2 changed files with 182 additions and 168 deletions
+180
View File
@@ -0,0 +1,180 @@
## Parameter binding — placeholder substitution and statement column metadata.
##
## Extracted from `executor.nim` (Task 3 of the executor split).
import std/strutils
import std/tables
import ../ast
import ../../protocol/wire
import context
# ----------------------------------------------------------------------
# Parameter binding
# ----------------------------------------------------------------------
proc doBindParams(node: Node, params: seq[WireValue], idx: var int): Node =
if node == nil: return nil
case node.kind
of nkPlaceholder:
if idx < params.len:
let p = params[idx]
inc idx
case p.kind
of fkString: return Node(kind: nkStringLit, strVal: p.strVal)
of fkInt64: return Node(kind: nkIntLit, intVal: int(p.int64Val))
of fkInt32: return Node(kind: nkIntLit, intVal: int(p.int32Val))
of fkInt16: return Node(kind: nkIntLit, intVal: int(p.int16Val))
of fkInt8: return Node(kind: nkIntLit, intVal: int(p.int8Val))
of fkFloat64: return Node(kind: nkFloatLit, floatVal: p.float64Val)
of fkFloat32: return Node(kind: nkFloatLit, floatVal: float(p.float32Val))
of fkBool: return Node(kind: nkBoolLit, boolVal: p.boolVal)
of fkNull: return Node(kind: nkNullLit)
else: return Node(kind: nkNullLit)
else:
return Node(kind: nkNullLit)
of nkBinOp:
result = Node(kind: nkBinOp, binOp: node.binOp,
line: node.line, col: node.col)
result.binLeft = doBindParams(node.binLeft, params, idx)
result.binRight = doBindParams(node.binRight, params, idx)
of nkUnaryOp:
result = Node(kind: nkUnaryOp, unOp: node.unOp,
line: node.line, col: node.col)
result.unOperand = doBindParams(node.unOperand, params, idx)
of nkFuncCall:
result = Node(kind: nkFuncCall, funcName: node.funcName,
line: node.line, col: node.col)
result.funcArgs = @[]
for arg in node.funcArgs:
result.funcArgs.add(doBindParams(arg, params, idx))
of nkArrayLit:
result = Node(kind: nkArrayLit, line: node.line, col: node.col)
result.arrayElems = @[]
for e in node.arrayElems:
result.arrayElems.add(doBindParams(e, params, idx))
of nkStatementList:
result = Node(kind: nkStatementList, line: node.line, col: node.col)
result.stmts = @[]
for s in node.stmts:
result.stmts.add(doBindParams(s, params, idx))
of nkSelect:
result = Node(kind: nkSelect, line: node.line, col: node.col)
result.selDistinct = node.selDistinct
result.selResult = @[]
for e in node.selResult:
result.selResult.add(doBindParams(e, params, idx))
result.selFrom = node.selFrom # FROM doesn't have placeholders
result.selJoins = @[]
for j in node.selJoins:
var nj = Node(kind: nkJoin, joinKind: j.joinKind,
joinTarget: j.joinTarget, joinAlias: j.joinAlias,
line: j.line, col: j.col)
nj.joinOn = doBindParams(j.joinOn, params, idx)
result.selJoins.add(nj)
result.selWhere = doBindParams(node.selWhere, params, idx)
result.selGroupBy = @[]
for g in node.selGroupBy:
result.selGroupBy.add(doBindParams(g, params, idx))
result.selHaving = doBindParams(node.selHaving, params, idx)
result.selOrderBy = @[]
for o in node.selOrderBy:
var no = Node(kind: nkOrderBy, orderByDir: o.orderByDir,
line: o.line, col: o.col)
no.orderByExpr = doBindParams(o.orderByExpr, params, idx)
result.selOrderBy.add(no)
result.selLimit = doBindParams(node.selLimit, params, idx)
result.selOffset = doBindParams(node.selOffset, params, idx)
of nkInsert:
result = Node(kind: nkInsert, insTarget: node.insTarget,
line: node.line, col: node.col)
result.insFields = node.insFields
result.insValues = @[]
for v in node.insValues:
result.insValues.add(doBindParams(v, params, idx))
result.insReturning = node.insReturning
of nkUpdate:
result = Node(kind: nkUpdate, updTarget: node.updTarget,
updAlias: node.updAlias, line: node.line, col: node.col)
result.updSet = @[]
for s in node.updSet:
var ns = Node(kind: nkBinOp, binOp: s.binOp, line: s.line, col: s.col)
ns.binLeft = s.binLeft
ns.binRight = doBindParams(s.binRight, params, idx)
result.updSet.add(ns)
result.updWhere = doBindParams(node.updWhere, params, idx)
result.updReturning = node.updReturning
of nkWhere:
result = Node(kind: nkWhere, line: node.line, col: node.col)
result.whereExpr = doBindParams(node.whereExpr, params, idx)
of nkHaving:
result = Node(kind: nkHaving, line: node.line, col: node.col)
result.havingExpr = doBindParams(node.havingExpr, params, idx)
of nkLimit:
result = Node(kind: nkLimit, line: node.line, col: node.col)
result.limitExpr = doBindParams(node.limitExpr, params, idx)
of nkOffset:
result = Node(kind: nkOffset, line: node.line, col: node.col)
result.offsetExpr = doBindParams(node.offsetExpr, params, idx)
of nkReturning:
result = Node(kind: nkReturning, line: node.line, col: node.col)
result.retExprs = @[]
for e in node.retExprs:
result.retExprs.add(doBindParams(e, params, idx))
of nkDelete:
result = Node(kind: nkDelete, delTarget: node.delTarget,
delAlias: node.delAlias, line: node.line, col: node.col)
result.delWhere = doBindParams(node.delWhere, params, idx)
result.delReturning = node.delReturning
else:
result = node
proc bindParams*(node: Node, params: seq[WireValue]): Node =
var idx = 0
result = doBindParams(node, params, idx)
# ----------------------------------------------------------------------
# Statement metadata
# ----------------------------------------------------------------------
proc getSelectColumns*(stmt: Node): seq[string] =
result = @[]
if stmt.kind != nkSelect: return result
var seenAliases = initTable[string, int]()
for i, e in stmt.selResult:
var alias = ""
if e.exprAlias.len > 0:
alias = e.exprAlias
elif e.kind == nkIdent:
alias = e.identName
elif e.kind == nkPath and e.pathParts.len > 0:
alias = e.pathParts.join(".")
elif e.kind == nkFuncCall:
var aliasArgs: seq[string] = @[]
for arg in e.funcArgs:
aliasArgs.add(exprToSql(arg))
alias = e.funcName & "(" & aliasArgs.join(", ") & ")"
elif e.kind == nkStar:
alias = "*"
else:
alias = "col" & $i
if alias in seenAliases:
seenAliases[alias] += 1
alias = alias & "_" & $seenAliases[alias]
else:
seenAliases[alias] = 0
result.add(alias)
proc isDDL*(stmt: Node): bool =
case stmt.kind
of nkCreateTable, nkDropTable, nkAlterTable,
nkCreateView, nkDropView,
nkCreateIndex, nkDropIndex,
nkCreateTrigger, nkDropTrigger,
nkCreateUser, nkDropUser,
nkCreatePolicy, nkDropPolicy,
nkCreateGraph, nkDropGraph,
nkCreateDatabase, nkDropDatabase,
nkGrant, nkRevoke,
nkEnableRLS, nkDisableRLS:
result = true
else:
result = false