fix+refactor: soft keywords as identifiers, full test wiring, ORC crash docs

- parser: clause keywords (header, format, status, user, csv, ...) now work
  as identifiers everywhere; IMPORT/EXPORT accept FORMAT csv/HEADER true
- nimble test + CI run all 13 test suites (650 checks green)
- ExecutionContext.registry is now {.cursor.} (breaks registry<->ctx cycle)
- ORC crash reproduced and bisected (tests/orc_repro.py); ARC stays the MM
This commit is contained in:
2026-07-30 13:11:28 +03:00
parent ed5a71913c
commit 2d09edd9f7
9 changed files with 952 additions and 94 deletions
+6 -1
View File
@@ -113,7 +113,12 @@ type
outerRow*: Table[string, string] # outer query row for correlated subqueries
subqueryPlan*: IRPlan # current subquery plan being evaluated
currentDatabase*: string # name of the currently selected database
registry*: DatabaseRegistry # nil for single-DB mode
# The registry owns this context (registry -> DatabaseInfo -> ctx), so this
# back-reference is a non-owning cursor: it breaks the registry <-> ctx
# reference cycle. The registry always outlives its contexts (closeAll at
# shutdown). Note: breaking this cycle alone does NOT make ORC usable —
# the ORC crash under wire INSERT load persists (see tests/orc_repro.py).
registry* {.cursor.}: DatabaseRegistry # nil for single-DB mode
MigrationRecord* = object
name*: string
+103 -82
View File
@@ -35,7 +35,12 @@ proc match(p: var Parser, kind: TokenKind): bool =
return false
# Token kinds that can also serve as identifiers in table/column name positions
const identLikeKinds = {tkIdent, tkLabels, tkCount, tkSum, tkAvg, tkMin, tkMax, tkArrayAgg, tkStringAgg, tkJsonFmt, tkArray, tkVector, tkGraph, tkDocument}
const identLikeKinds = {tkIdent, tkLabels, tkCount, tkSum, tkAvg, tkMin, tkMax,
tkArrayAgg, tkStringAgg, tkJsonFmt, tkArray, tkVector, tkGraph, tkDocument,
tkHeader, tkFormat, tkDelimiter, tkBatch, tkCsv, tkNdjson,
tkStatus, tkMigration, tkApply, tkUp, tkDown, tkDryRun,
tkUser, tkPolicy, tkEnable, tkDisable, tkRecover,
tkBefore, tkAfter, tkInstead, tkOf}
proc expectIdent(p: var Parser): Token =
## Expect a token that can serve as an identifier (table name, column name, alias, etc.).
@@ -81,7 +86,11 @@ proc parsePrimary(p: var Parser): Node =
of tkCurrentRole:
discard p.advance()
Node(kind: nkCurrentRole, line: tok.line, col: tok.col)
of tkIdent, tkLabels, tkRowNumber, tkRank, tkDenseRank, tkLead, tkLag, tkFirstValue, tkLastValue, tkNtile:
of tkIdent, tkLabels, tkRowNumber, tkRank, tkDenseRank, tkLead, tkLag, tkFirstValue, tkLastValue, tkNtile,
tkHeader, tkFormat, tkDelimiter, tkBatch, tkCsv, tkNdjson,
tkStatus, tkMigration, tkApply, tkUp, tkDown, tkDryRun,
tkUser, tkPolicy, tkEnable, tkDisable, tkRecover,
tkBefore, tkAfter, tkInstead, tkOf:
discard p.advance()
let funcName = tok.value
# Check for function call: ident(...)
@@ -105,7 +114,7 @@ proc parsePrimary(p: var Parser): Node =
var parts = @[funcName]
while p.peek().kind == tkDot:
discard p.advance() # consume .
parts.add(p.expect(tkIdent).value)
parts.add(p.expectIdent().value)
if parts.len == 1:
return Node(kind: nkIdent, identName: funcName, line: tok.line, col: tok.col)
return Node(kind: nkPath, pathParts: parts, line: tok.line, col: tok.col)
@@ -462,7 +471,7 @@ proc parseWith(p: var Parser): Node =
isRecursive = true
# Parse first CTE
let cteName = p.expect(tkIdent).value
let cteName = p.expectIdent().value
discard p.expect(tkAs)
discard p.expect(tkLParen)
let cteQuery = p.parseSelect()
@@ -471,7 +480,7 @@ proc parseWith(p: var Parser): Node =
# Parse additional CTEs
while p.match(tkComma):
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
discard p.expect(tkAs)
discard p.expect(tkLParen)
let query = p.parseSelect()
@@ -498,12 +507,12 @@ proc parseSelect(p: var Parser): Node =
result.selResult = @[]
var expr = p.parseExpr()
if p.match(tkAs):
expr.exprAlias = p.expect(tkIdent).value
expr.exprAlias = p.expectIdent().value
result.selResult.add(expr)
while p.match(tkComma):
expr = p.parseExpr()
if p.match(tkAs):
expr.exprAlias = p.expect(tkIdent).value
expr.exprAlias = p.expectIdent().value
result.selResult.add(expr)
# Parse FROM
@@ -516,7 +525,7 @@ proc parseSelect(p: var Parser): Node =
discard p.expect(tkRParen)
var alias = ""
if p.match(tkAs):
alias = p.expect(tkIdent).value
alias = p.expectIdent().value
elif p.peek().kind == tkIdent:
alias = p.advance().value
result.selFrom = Node(kind: nkFrom, fromTable: "(subquery)",
@@ -525,7 +534,7 @@ proc parseSelect(p: var Parser): Node =
# GRAPH_TABLE(name MATCH (pattern) COLUMNS (cols))
discard p.advance()
discard p.expect(tkLParen)
let graphName = p.expect(tkIdent).value
let graphName = p.expectIdent().value
var hasMatch = p.match(tkMatch)
var patternNodes: seq[string]
var patternEdges: seq[string]
@@ -595,7 +604,7 @@ proc parseSelect(p: var Parser): Node =
if p.peek().kind in {tkIdent, tkLabels, tkEdge, tkGraph, tkRank, tkBfs, tkDfs, tkMatch, tkColumns, tkEnd, tkSrc, tkDst, tkMerge}:
colName &= "." & p.advance().value
else:
colName &= "." & p.expect(tkIdent).value
colName &= "." & p.expectIdent().value
returnCols.add(colName)
while p.match(tkComma):
if p.peek().kind in {tkIdent, tkLabels, tkEdge, tkGraph, tkRank, tkEnd, tkMatch, tkColumns, tkSrc, tkDst, tkBfs, tkDfs, tkMerge}:
@@ -605,7 +614,7 @@ proc parseSelect(p: var Parser): Node =
if p.peek().kind in {tkIdent, tkLabels, tkEdge, tkGraph, tkRank, tkBfs, tkDfs, tkMatch, tkColumns, tkEnd, tkSrc, tkDst, tkMerge}:
colName &= "." & p.advance().value
else:
colName &= "." & p.expect(tkIdent).value
colName &= "." & p.expectIdent().value
returnCols.add(colName)
if p.match(tkAs):
discard p.advance()
@@ -629,10 +638,10 @@ proc parseSelect(p: var Parser): Node =
gtDirection: "out", gtEnd: endNode, gtMaxDepth: maxDepth,
gtReturnCols: returnCols, gtAlgo: algo, line: tok.line, col: tok.col)
else:
let tableTok = p.expect(tkIdent)
let tableTok = p.expectIdent()
var alias = ""
if p.match(tkAs):
alias = p.expect(tkIdent).value
alias = p.expectIdent().value
elif p.peek().kind == tkIdent:
alias = p.advance().value
result.selFrom = Node(kind: nkFrom, fromTable: tableTok.value,
@@ -641,10 +650,10 @@ proc parseSelect(p: var Parser): Node =
# Comma join: FROM t1, t2 → implicit CROSS JOIN
while p.peek().kind == tkComma:
discard p.advance()
let nextTableTok = p.expect(tkIdent)
let nextTableTok = p.expectIdent()
var nextAlias = ""
if p.match(tkAs):
nextAlias = p.expect(tkIdent).value
nextAlias = p.expectIdent().value
elif p.peek().kind == tkIdent:
nextAlias = p.advance().value
let joinNode = Node(kind: nkJoin, joinKind: jkCross,
@@ -660,7 +669,7 @@ proc parseSelect(p: var Parser): Node =
discard p.expect(tkLParen)
let aggFunc = p.parseExpr() # e.g. SUM(salary)
discard p.expect(tkFor)
let forCol = p.expect(tkIdent).value
let forCol = p.expectIdent().value
discard p.expect(tkIn)
discard p.expect(tkLParen)
var inValues: seq[string] = @[]
@@ -675,15 +684,15 @@ proc parseSelect(p: var Parser): Node =
elif p.peek().kind == tkUnpivot:
discard p.advance()
discard p.expect(tkLParen)
let valCol = p.expect(tkIdent).value
let valCol = p.expectIdent().value
discard p.expect(tkFor)
let forCol = p.expect(tkIdent).value
let forCol = p.expectIdent().value
discard p.expect(tkIn)
discard p.expect(tkLParen)
var inCols: seq[string] = @[]
inCols.add(p.expect(tkIdent).value)
inCols.add(p.expectIdent().value)
while p.match(tkComma):
inCols.add(p.expect(tkIdent).value)
inCols.add(p.expectIdent().value)
discard p.expect(tkRParen)
discard p.expect(tkRParen)
result.selFrom = Node(kind: nkUnpivot, unpivotSource: result.selFrom,
@@ -718,15 +727,15 @@ proc parseSelect(p: var Parser): Node =
let subquery = p.parseSelect()
discard p.expect(tkRParen)
if p.match(tkAs):
joinAlias = p.expect(tkIdent).value
joinAlias = p.expectIdent().value
elif p.peek().kind == tkIdent:
joinAlias = p.advance().value
joinTarget = Node(kind: nkSubquery, subQuery: subquery,
line: tok.line, col: tok.col)
else:
let joinTable = p.expect(tkIdent)
let joinTable = p.expectIdent()
if p.match(tkAs):
joinAlias = p.expect(tkIdent).value
joinAlias = p.expectIdent().value
elif p.peek().kind == tkIdent:
joinAlias = p.advance().value
joinTarget = Node(kind: nkFrom, fromTable: joinTable.value,
@@ -846,7 +855,7 @@ proc parseSelect(p: var Parser): Node =
proc parseInsert(p: var Parser): Node =
let tok = p.expect(tkInsert)
discard p.match(tkInto) # optional INTO
let target = p.expect(tkIdent).value
let target = p.expectIdent().value
result = Node(kind: nkInsert, insTarget: target, line: tok.line, col: tok.col)
result.insFields = @[]
result.insValues = @[]
@@ -892,18 +901,18 @@ proc parseInsert(p: var Parser): Node =
proc parseUpdate(p: var Parser): Node =
let tok = p.expect(tkUpdate)
let target = p.expect(tkIdent).value
let target = p.expectIdent().value
result = Node(kind: nkUpdate, updTarget: target, line: tok.line, col: tok.col)
if p.match(tkSet):
result.updSet = @[]
let field = p.expect(tkIdent).value
let field = p.expectIdent().value
discard p.match(tkEq) # = or :=
let val = p.parseExpr()
result.updSet.add(Node(kind: nkBinOp, binOp: bkAssign,
binLeft: Node(kind: nkIdent, identName: field),
binRight: val))
while p.match(tkComma):
let f = p.expect(tkIdent).value
let f = p.expectIdent().value
discard p.match(tkEq)
let v = p.parseExpr()
result.updSet.add(Node(kind: nkBinOp, binOp: bkAssign,
@@ -920,7 +929,7 @@ proc parseUpdate(p: var Parser): Node =
proc parseDelete(p: var Parser): Node =
let tok = p.expect(tkDelete)
discard p.match(tkFrom) # optional FROM keyword
let target = p.expect(tkIdent).value
let target = p.expectIdent().value
result = Node(kind: nkDelete, delTarget: target, line: tok.line, col: tok.col)
if p.match(tkWhere):
result.delWhere = Node(kind: nkWhere, whereExpr: p.parseExpr())
@@ -934,9 +943,9 @@ proc parseMerge(p: var Parser): Node =
let tok = p.expect(tkMerge)
discard p.match(tkInto) # optional INTO
result = Node(kind: nkMerge, line: tok.line, col: tok.col)
result.mergeTarget = p.expect(tkIdent).value
result.mergeTarget = p.expectIdent().value
if p.match(tkAs):
result.mergeTargetAlias = p.expect(tkIdent).value
result.mergeTargetAlias = p.expectIdent().value
elif p.peek().kind == tkIdent:
result.mergeTargetAlias = p.advance().value
discard p.expect(tkUsing)
@@ -946,10 +955,10 @@ proc parseMerge(p: var Parser): Node =
result.mergeSource = p.parseSelect()
discard p.expect(tkRParen)
else:
let srcTable = p.expect(tkIdent).value
let srcTable = p.expectIdent().value
result.mergeSource = Node(kind: nkIdent, identName: srcTable, line: tok.line, col: tok.col)
if p.match(tkAs):
result.mergeSourceAlias = p.expect(tkIdent).value
result.mergeSourceAlias = p.expectIdent().value
elif p.peek().kind == tkIdent:
result.mergeSourceAlias = p.advance().value
discard p.expect(tkOn)
@@ -977,9 +986,9 @@ proc parseMerge(p: var Parser): Node =
elif p.peek().kind == tkInsert:
discard p.advance()
discard p.expect(tkLParen)
result.mergeNotMatchedInsert.add(Node(kind: nkIdent, identName: p.expect(tkIdent).value))
result.mergeNotMatchedInsert.add(Node(kind: nkIdent, identName: p.expectIdent().value))
while p.match(tkComma):
result.mergeNotMatchedInsert.add(Node(kind: nkIdent, identName: p.expect(tkIdent).value))
result.mergeNotMatchedInsert.add(Node(kind: nkIdent, identName: p.expectIdent().value))
discard p.expect(tkRParen)
discard p.expect(tkValues)
discard p.expect(tkLParen)
@@ -990,13 +999,13 @@ proc parseMerge(p: var Parser): Node =
elif p.peek().kind == tkUpdate:
discard p.advance()
discard p.expect(tkSet)
let col = p.expect(tkIdent).value
let col = p.expectIdent().value
discard p.expect(tkEq)
result.mergeMatchedUpdate.add(Node(kind: nkBinOp, binOp: bkAssign,
binLeft: Node(kind: nkIdent, identName: col),
binRight: p.parseExpr()))
while p.match(tkComma):
let col2 = p.expect(tkIdent).value
let col2 = p.expectIdent().value
discard p.expect(tkEq)
result.mergeMatchedUpdate.add(Node(kind: nkBinOp, binOp: bkAssign,
binLeft: Node(kind: nkIdent, identName: col2),
@@ -1005,7 +1014,7 @@ proc parseMerge(p: var Parser): Node =
proc parseCreateType(p: var Parser): Node =
let tok = p.expect(tkCreate)
discard p.expect(tkType)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkCreateType, ctName: name, line: tok.line, col: tok.col)
result.ctBases = @[]
if p.match(tkIdent):
@@ -1023,10 +1032,10 @@ proc parseCreateType(p: var Parser): Node =
if p.peek().kind == tkMulti:
discard p.advance()
isMulti = true
let fieldTok = p.expect(tkIdent)
let fieldTok = p.expectIdent()
if p.peek().kind == tkArrow:
discard p.advance()
let target = p.expect(tkIdent).value
let target = p.expectIdent().value
result.ctLinks.add(Node(kind: nkLinkDef,
ldName: fieldTok.value, ldTarget: target,
ldRequired: isRequired,
@@ -1034,7 +1043,7 @@ proc parseCreateType(p: var Parser): Node =
else:
var typeName = ""
if p.match(tkColon):
typeName = p.expect(tkIdent).value
typeName = p.expectIdent().value
result.ctProperties.add(Node(kind: nkPropertyDef,
pdName: fieldTok.value, pdType: typeName,
pdRequired: isRequired))
@@ -1270,14 +1279,14 @@ proc parseAlterTable(p: var Parser): Node =
if p.peek().kind == tkEnable:
discard p.advance()
discard p.expect(tkRow) # ROW
discard p.expect(tkIdent) # LEVEL
discard p.expect(tkIdent) # SECURITY
discard p.expectIdent() # LEVEL
discard p.expectIdent() # SECURITY
return Node(kind: nkEnableRLS, erlsTable: tableName, line: tok.line, col: tok.col)
elif p.peek().kind == tkDisable:
discard p.advance()
discard p.expect(tkRow) # ROW
discard p.expect(tkIdent) # LEVEL
discard p.expect(tkIdent) # SECURITY
discard p.expectIdent() # LEVEL
discard p.expectIdent() # SECURITY
return Node(kind: nkDisableRLS, drlsTable: tableName, line: tok.line, col: tok.col)
result = Node(kind: nkAlterTable, line: tok.line, col: tok.col)
result.altName = tableName
@@ -1349,10 +1358,10 @@ proc parseCreateView(p: var Parser): Node =
var orReplace = false
if p.peek().kind == tkIdent and p.peek().value.toLower() == "or":
discard p.advance()
discard p.expect(tkIdent) # REPLACE
discard p.expectIdent() # REPLACE
orReplace = true
discard p.expect(tkView)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
discard p.expect(tkAs)
let query = p.parseSelect()
result = Node(kind: nkCreateView, cvName: name, cvQuery: query,
@@ -1366,14 +1375,14 @@ proc parseDropView(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkDropView, dvName: name, dvIfExists: ifExists,
line: tok.line, col: tok.col)
proc parseCreateTrigger(p: var Parser): Node =
let tok = p.expect(tkCreate)
discard p.expect(tkTrigger)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
# Parse timing: BEFORE | AFTER | INSTEAD OF
var timing = ""
let timingTok = p.peek()
@@ -1404,7 +1413,7 @@ proc parseCreateTrigger(p: var Parser): Node =
else:
raise newException(ValueError, "Expected INSERT, UPDATE, or DELETE in TRIGGER definition")
discard p.expect(tkOn)
let tableName = p.expect(tkIdent).value
let tableName = p.expectIdent().value
discard p.expect(tkAs)
# Parse action as raw string until end of statement
var actionStr = ""
@@ -1425,7 +1434,7 @@ proc parseDropTrigger(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkDropTrigger, trigDropName: name, trigDropIfExists: ifExists,
line: tok.line, col: tok.col)
@@ -1437,13 +1446,13 @@ proc parseDropIndex(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkDropIndex, diName: name, line: tok.line, col: tok.col)
proc parseCreateMigration(p: var Parser): Node =
let tok = p.expect(tkCreate)
discard p.expect(tkMigration)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
var upBody = ""
var downBody = ""
if p.peek().kind == tkAs:
@@ -1463,7 +1472,7 @@ proc parseCreateMigration(p: var Parser): Node =
discard p.advance()
section = "down"
elif sectionTok.kind == tkIdent:
section = p.expect(tkIdent).value.toLower()
section = p.expectIdent().value.toLower()
else:
raise newException(ValueError, "Expected UP or DOWN in migration body, got: " & $sectionTok.kind)
discard p.expect(tkColon)
@@ -1492,7 +1501,7 @@ proc parseCreateMigration(p: var Parser): Node =
proc parseApplyMigration(p: var Parser): Node =
let tok = p.expect(tkApply)
discard p.expect(tkMigration)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkApplyMigration, amName: name, line: tok.line, col: tok.col)
proc parseMigrationStatus(p: var Parser): Node =
@@ -1519,7 +1528,7 @@ proc parseMigrationDown(p: var Parser): Node =
proc parseMigrationDryRun(p: var Parser): Node =
let tok = p.expect(tkMigration)
discard p.expect(tkDryRun)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkMigrationDryRun, mdrName: name, line: tok.line, col: tok.col)
proc parseImportFrom(p: var Parser): Node =
@@ -1527,7 +1536,7 @@ proc parseImportFrom(p: var Parser): Node =
discard p.expect(tkFrom)
let path = p.expect(tkStringLit).value
discard p.expect(tkInto)
let table = p.expect(tkIdent).value
let table = p.expectIdent().value
var format = "csv"
var delimiter = ','
var hasHeader = true
@@ -1536,14 +1545,20 @@ proc parseImportFrom(p: var Parser): Node =
let kw = p.advance()
case kw.kind
of tkFormat:
let fmt = p.expect(tkIdent).value.toLower()
format = fmt
format = p.expectIdent().value.toLower()
of tkDelimiter:
let delim = p.expect(tkStringLit).value
if delim.len > 0: delimiter = delim[0]
of tkHeader:
let hdr = p.expect(tkIdent).value.toLower()
hasHeader = hdr == "true" or hdr == "yes"
if p.peek().kind == tkTrue:
discard p.advance()
hasHeader = true
elif p.peek().kind == tkFalse:
discard p.advance()
hasHeader = false
else:
let hdr = p.expectIdent().value.toLower()
hasHeader = hdr == "true" or hdr == "yes"
of tkBatch:
batchSize = parseInt(p.expect(tkIntLit).value)
else: discard
@@ -1557,7 +1572,7 @@ proc parseExportTo(p: var Parser): Node =
discard p.expect(tkTo)
let path = p.expect(tkStringLit).value
discard p.expect(tkFrom)
let table = p.expect(tkIdent).value
let table = p.expectIdent().value
var format = "csv"
var delimiter = ','
var includeHeader = true
@@ -1565,14 +1580,20 @@ proc parseExportTo(p: var Parser): Node =
let kw = p.advance()
case kw.kind
of tkFormat:
let fmt = p.expect(tkIdent).value.toLower()
format = fmt
format = p.expectIdent().value.toLower()
of tkDelimiter:
let delim = p.expect(tkStringLit).value
if delim.len > 0: delimiter = delim[0]
of tkHeader:
let hdr = p.expect(tkIdent).value.toLower()
includeHeader = hdr == "true" or hdr == "yes"
if p.peek().kind == tkTrue:
discard p.advance()
includeHeader = true
elif p.peek().kind == tkFalse:
discard p.advance()
includeHeader = false
else:
let hdr = p.expectIdent().value.toLower()
includeHeader = hdr == "true" or hdr == "yes"
else: discard
result = Node(kind: nkExportTo, expPath: path, expTable: table,
expFormat: format, expDelimiter: delimiter,
@@ -1582,7 +1603,7 @@ proc parseExportTo(p: var Parser): Node =
proc parseCreateUser(p: var Parser): Node =
let tok = p.expect(tkCreate)
discard p.expect(tkUser)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
var password = ""
var isSuper = false
if p.peek().kind == tkWith:
@@ -1611,16 +1632,16 @@ proc parseDropUser(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkDropUser, duName: name, duIfExists: ifExists,
line: tok.line, col: tok.col)
proc parseCreatePolicy(p: var Parser): Node =
let tok = p.expect(tkCreate)
discard p.expect(tkPolicy)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
discard p.expect(tkOn)
let tableName = p.expect(tkIdent).value
let tableName = p.expectIdent().value
var cmd = "ALL"
var usingNode: Node = nil
var withCheckNode: Node = nil
@@ -1652,9 +1673,9 @@ proc parseDropPolicy(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
discard p.expect(tkOn)
let tableName = p.expect(tkIdent).value
let tableName = p.expectIdent().value
result = Node(kind: nkDropPolicy, dpName: name, dpTable: tableName,
dpIfExists: ifExists, line: tok.line, col: tok.col)
@@ -1669,9 +1690,9 @@ proc parseGrant(p: var Parser): Node =
else:
raise newException(ValueError, "Expected privilege in GRANT")
discard p.expect(tkOn)
let tableName = p.expect(tkIdent).value
let tableName = p.expectIdent().value
discard p.expect(tkTo)
let grantee = p.expect(tkIdent).value
let grantee = p.expectIdent().value
result = Node(kind: nkGrant, grPrivilege: priv, grTable: tableName,
grGrantee: grantee, line: tok.line, col: tok.col)
@@ -1686,19 +1707,19 @@ proc parseRevoke(p: var Parser): Node =
else:
raise newException(ValueError, "Expected privilege in REVOKE")
discard p.expect(tkOn)
let tableName = p.expect(tkIdent).value
let tableName = p.expectIdent().value
discard p.expect(tkFrom)
let grantee = p.expect(tkIdent).value
let grantee = p.expectIdent().value
result = Node(kind: nkRevoke, rvPrivilege: priv, rvTable: tableName,
rvGrantee: grantee, line: tok.line, col: tok.col)
proc parseSetVar(p: var Parser): Node =
let tok = p.expect(tkSet)
var varName = p.expect(tkIdent).value
var varName = p.expectIdent().value
while p.peek().kind == tkDot:
discard p.advance()
varName.add(".")
varName.add(p.expect(tkIdent).value)
varName.add(p.expectIdent().value)
if p.match(tkEq) or p.match(tkTo):
discard
let valTok = p.peek()
@@ -1730,7 +1751,7 @@ proc parseCreateGraph(p: var Parser): Node =
discard p.expect(tkNot)
discard p.expect(tkExists)
ifNotExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkCreateGraph, cgName: name, cgIfNotExists: ifNotExists,
line: tok.line, col: tok.col)
@@ -1742,7 +1763,7 @@ proc parseDropGraph(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkDropGraph, dgName: name, dgIfExists: ifExists,
line: tok.line, col: tok.col)
@@ -1755,7 +1776,7 @@ proc parseCreateDatabase(p: var Parser): Node =
discard p.expect(tkNot)
discard p.expect(tkExists)
ifNotExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkCreateDatabase, cdDbName: name, cdIfNotExists: ifNotExists,
line: tok.line, col: tok.col)
@@ -1767,13 +1788,13 @@ proc parseDropDatabase(p: var Parser): Node =
discard p.advance()
discard p.expect(tkExists)
ifExists = true
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkDropDatabase, ddDbName: name, ddIfExists: ifExists,
line: tok.line, col: tok.col)
proc parseUseDatabase(p: var Parser): Node =
let tok = p.expect(tkUse)
let name = p.expect(tkIdent).value
let name = p.expectIdent().value
result = Node(kind: nkUseDatabase, udDbName: name,
line: tok.line, col: tok.col)