lib: Trim .nim files trailing whitespace
via OSX: find . -name '*.nim' -exec sed -i '' -E 's/[[:space:]]+$//' {} +
This commit is contained in:
parent
d681812465
commit
43bddf62dd
67 changed files with 2435 additions and 2435 deletions
|
|
@ -7,7 +7,7 @@
|
|||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## The ``parsesql`` module implements a high performance SQL file
|
||||
## The ``parsesql`` module implements a high performance SQL file
|
||||
## parser. It parses PostgreSQL syntax and the SQL ANSI standard.
|
||||
|
||||
import
|
||||
|
|
@ -37,11 +37,11 @@ type
|
|||
tkBracketLe, ## '['
|
||||
tkBracketRi, ## ']'
|
||||
tkDot ## '.'
|
||||
|
||||
|
||||
Token = object # a token
|
||||
kind: TokKind # the type of the token
|
||||
literal: string # the parsed (string) literal
|
||||
|
||||
|
||||
SqlLexer* = object of BaseLexer ## the parser object.
|
||||
filename: string
|
||||
|
||||
|
|
@ -55,82 +55,82 @@ const
|
|||
";", ":", ",", "(", ")", "[", "]", "."
|
||||
]
|
||||
|
||||
proc open(L: var SqlLexer, input: Stream, filename: string) =
|
||||
proc open(L: var SqlLexer, input: Stream, filename: string) =
|
||||
lexbase.open(L, input)
|
||||
L.filename = filename
|
||||
|
||||
proc close(L: var SqlLexer) =
|
||||
|
||||
proc close(L: var SqlLexer) =
|
||||
lexbase.close(L)
|
||||
|
||||
proc getColumn(L: SqlLexer): int =
|
||||
proc getColumn(L: SqlLexer): int =
|
||||
## get the current column the parser has arrived at.
|
||||
result = getColNumber(L, L.bufpos)
|
||||
|
||||
proc getLine(L: SqlLexer): int =
|
||||
proc getLine(L: SqlLexer): int =
|
||||
result = L.lineNumber
|
||||
|
||||
proc handleHexChar(c: var SqlLexer, xi: var int) =
|
||||
proc handleHexChar(c: var SqlLexer, xi: var int) =
|
||||
case c.buf[c.bufpos]
|
||||
of '0'..'9':
|
||||
of '0'..'9':
|
||||
xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0'))
|
||||
inc(c.bufpos)
|
||||
of 'a'..'f':
|
||||
of 'a'..'f':
|
||||
xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10)
|
||||
inc(c.bufpos)
|
||||
of 'A'..'F':
|
||||
of 'A'..'F':
|
||||
xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10)
|
||||
inc(c.bufpos)
|
||||
else:
|
||||
else:
|
||||
discard
|
||||
|
||||
proc handleOctChar(c: var SqlLexer, xi: var int) =
|
||||
proc handleOctChar(c: var SqlLexer, xi: var int) =
|
||||
if c.buf[c.bufpos] in {'0'..'7'}:
|
||||
xi = (xi shl 3) or (ord(c.buf[c.bufpos]) - ord('0'))
|
||||
inc(c.bufpos)
|
||||
|
||||
proc getEscapedChar(c: var SqlLexer, tok: var Token) =
|
||||
proc getEscapedChar(c: var SqlLexer, tok: var Token) =
|
||||
inc(c.bufpos)
|
||||
case c.buf[c.bufpos]
|
||||
of 'n', 'N':
|
||||
of 'n', 'N':
|
||||
add(tok.literal, '\L')
|
||||
inc(c.bufpos)
|
||||
of 'r', 'R', 'c', 'C':
|
||||
of 'r', 'R', 'c', 'C':
|
||||
add(tok.literal, '\c')
|
||||
inc(c.bufpos)
|
||||
of 'l', 'L':
|
||||
of 'l', 'L':
|
||||
add(tok.literal, '\L')
|
||||
inc(c.bufpos)
|
||||
of 'f', 'F':
|
||||
of 'f', 'F':
|
||||
add(tok.literal, '\f')
|
||||
inc(c.bufpos)
|
||||
of 'e', 'E':
|
||||
of 'e', 'E':
|
||||
add(tok.literal, '\e')
|
||||
inc(c.bufpos)
|
||||
of 'a', 'A':
|
||||
of 'a', 'A':
|
||||
add(tok.literal, '\a')
|
||||
inc(c.bufpos)
|
||||
of 'b', 'B':
|
||||
of 'b', 'B':
|
||||
add(tok.literal, '\b')
|
||||
inc(c.bufpos)
|
||||
of 'v', 'V':
|
||||
of 'v', 'V':
|
||||
add(tok.literal, '\v')
|
||||
inc(c.bufpos)
|
||||
of 't', 'T':
|
||||
of 't', 'T':
|
||||
add(tok.literal, '\t')
|
||||
inc(c.bufpos)
|
||||
of '\'', '\"':
|
||||
of '\'', '\"':
|
||||
add(tok.literal, c.buf[c.bufpos])
|
||||
inc(c.bufpos)
|
||||
of '\\':
|
||||
of '\\':
|
||||
add(tok.literal, '\\')
|
||||
inc(c.bufpos)
|
||||
of 'x', 'X':
|
||||
of 'x', 'X':
|
||||
inc(c.bufpos)
|
||||
var xi = 0
|
||||
handleHexChar(c, xi)
|
||||
handleHexChar(c, xi)
|
||||
add(tok.literal, chr(xi))
|
||||
of '0'..'7':
|
||||
of '0'..'7':
|
||||
var xi = 0
|
||||
handleOctChar(c, xi)
|
||||
handleOctChar(c, xi)
|
||||
|
|
@ -138,20 +138,20 @@ proc getEscapedChar(c: var SqlLexer, tok: var Token) =
|
|||
if (xi <= 255): add(tok.literal, chr(xi))
|
||||
else: tok.kind = tkInvalid
|
||||
else: tok.kind = tkInvalid
|
||||
|
||||
proc handleCRLF(c: var SqlLexer, pos: int): int =
|
||||
|
||||
proc handleCRLF(c: var SqlLexer, pos: int): int =
|
||||
case c.buf[pos]
|
||||
of '\c': result = lexbase.handleCR(c, pos)
|
||||
of '\L': result = lexbase.handleLF(c, pos)
|
||||
else: result = pos
|
||||
|
||||
proc skip(c: var SqlLexer) =
|
||||
proc skip(c: var SqlLexer) =
|
||||
var pos = c.bufpos
|
||||
var buf = c.buf
|
||||
var nested = 0
|
||||
while true:
|
||||
while true:
|
||||
case buf[pos]
|
||||
of ' ', '\t':
|
||||
of ' ', '\t':
|
||||
inc(pos)
|
||||
of '-':
|
||||
if buf[pos+1] == '-':
|
||||
|
|
@ -164,7 +164,7 @@ proc skip(c: var SqlLexer) =
|
|||
while true:
|
||||
case buf[pos]
|
||||
of '\0': break
|
||||
of '\c', '\L':
|
||||
of '\c', '\L':
|
||||
pos = handleCRLF(c, pos)
|
||||
buf = c.buf
|
||||
of '*':
|
||||
|
|
@ -182,20 +182,20 @@ proc skip(c: var SqlLexer) =
|
|||
inc(pos)
|
||||
else: inc(pos)
|
||||
else: break
|
||||
of '\c', '\L':
|
||||
of '\c', '\L':
|
||||
pos = handleCRLF(c, pos)
|
||||
buf = c.buf
|
||||
else:
|
||||
else:
|
||||
break # EndOfFile also leaves the loop
|
||||
c.bufpos = pos
|
||||
|
||||
proc getString(c: var SqlLexer, tok: var Token, kind: TokKind) =
|
||||
|
||||
proc getString(c: var SqlLexer, tok: var Token, kind: TokKind) =
|
||||
var pos = c.bufpos + 1
|
||||
var buf = c.buf
|
||||
tok.kind = kind
|
||||
block parseLoop:
|
||||
while true:
|
||||
while true:
|
||||
while true:
|
||||
var ch = buf[pos]
|
||||
if ch == '\'':
|
||||
if buf[pos+1] == '\'':
|
||||
|
|
@ -203,15 +203,15 @@ proc getString(c: var SqlLexer, tok: var Token, kind: TokKind) =
|
|||
add(tok.literal, '\'')
|
||||
else:
|
||||
inc(pos)
|
||||
break
|
||||
elif ch in {'\c', '\L', lexbase.EndOfFile}:
|
||||
break
|
||||
elif ch in {'\c', '\L', lexbase.EndOfFile}:
|
||||
tok.kind = tkInvalid
|
||||
break parseLoop
|
||||
elif (ch == '\\') and kind == tkEscapeConstant:
|
||||
elif (ch == '\\') and kind == tkEscapeConstant:
|
||||
c.bufpos = pos
|
||||
getEscapedChar(c, tok)
|
||||
pos = c.bufpos
|
||||
else:
|
||||
else:
|
||||
add(tok.literal, ch)
|
||||
inc(pos)
|
||||
c.bufpos = pos
|
||||
|
|
@ -227,7 +227,7 @@ proc getString(c: var SqlLexer, tok: var Token, kind: TokKind) =
|
|||
else: break parseLoop
|
||||
c.bufpos = pos
|
||||
|
||||
proc getDollarString(c: var SqlLexer, tok: var Token) =
|
||||
proc getDollarString(c: var SqlLexer, tok: var Token) =
|
||||
var pos = c.bufpos + 1
|
||||
var buf = c.buf
|
||||
tok.kind = tkDollarQuotedConstant
|
||||
|
|
@ -241,7 +241,7 @@ proc getDollarString(c: var SqlLexer, tok: var Token) =
|
|||
return
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '\c', '\L':
|
||||
of '\c', '\L':
|
||||
pos = handleCRLF(c, pos)
|
||||
buf = c.buf
|
||||
add(tok.literal, "\L")
|
||||
|
|
@ -263,10 +263,10 @@ proc getDollarString(c: var SqlLexer, tok: var Token) =
|
|||
inc(pos)
|
||||
c.bufpos = pos
|
||||
|
||||
proc getSymbol(c: var SqlLexer, tok: var Token) =
|
||||
proc getSymbol(c: var SqlLexer, tok: var Token) =
|
||||
var pos = c.bufpos
|
||||
var buf = c.buf
|
||||
while true:
|
||||
while true:
|
||||
add(tok.literal, buf[pos])
|
||||
inc(pos)
|
||||
if buf[pos] notin {'a'..'z','A'..'Z','0'..'9','_','$', '\128'..'\255'}:
|
||||
|
|
@ -274,7 +274,7 @@ proc getSymbol(c: var SqlLexer, tok: var Token) =
|
|||
c.bufpos = pos
|
||||
tok.kind = tkIdentifier
|
||||
|
||||
proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) =
|
||||
proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) =
|
||||
var pos = c.bufpos + 1
|
||||
var buf = c.buf
|
||||
tok.kind = tkQuotedIdentifier
|
||||
|
|
@ -287,7 +287,7 @@ proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) =
|
|||
else:
|
||||
inc(pos)
|
||||
break
|
||||
elif ch in {'\c', '\L', lexbase.EndOfFile}:
|
||||
elif ch in {'\c', '\L', lexbase.EndOfFile}:
|
||||
tok.kind = tkInvalid
|
||||
break
|
||||
else:
|
||||
|
|
@ -300,15 +300,15 @@ proc getBitHexString(c: var SqlLexer, tok: var Token, validChars: set[char]) =
|
|||
var buf = c.buf
|
||||
block parseLoop:
|
||||
while true:
|
||||
while true:
|
||||
while true:
|
||||
var ch = buf[pos]
|
||||
if ch in validChars:
|
||||
add(tok.literal, ch)
|
||||
inc(pos)
|
||||
inc(pos)
|
||||
elif ch == '\'':
|
||||
inc(pos)
|
||||
break
|
||||
else:
|
||||
else:
|
||||
tok.kind = tkInvalid
|
||||
break parseLoop
|
||||
c.bufpos = pos
|
||||
|
|
@ -353,7 +353,7 @@ proc getNumeric(c: var SqlLexer, tok: var Token) =
|
|||
inc(pos)
|
||||
else:
|
||||
tok.kind = tkInvalid
|
||||
c.bufpos = pos
|
||||
c.bufpos = pos
|
||||
|
||||
proc getOperator(c: var SqlLexer, tok: var Token) =
|
||||
const operators = {'+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%',
|
||||
|
|
@ -381,12 +381,12 @@ proc getOperator(c: var SqlLexer, tok: var Token) =
|
|||
inc(pos)
|
||||
c.bufpos = pos
|
||||
|
||||
proc getTok(c: var SqlLexer, tok: var Token) =
|
||||
proc getTok(c: var SqlLexer, tok: var Token) =
|
||||
tok.kind = tkInvalid
|
||||
setLen(tok.literal, 0)
|
||||
skip(c)
|
||||
case c.buf[c.bufpos]
|
||||
of ';':
|
||||
of ';':
|
||||
tok.kind = tkSemicolon
|
||||
inc(c.bufpos)
|
||||
add(tok.literal, ';')
|
||||
|
|
@ -394,15 +394,15 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
|||
tok.kind = tkComma
|
||||
inc(c.bufpos)
|
||||
add(tok.literal, ',')
|
||||
of ':':
|
||||
of ':':
|
||||
tok.kind = tkColon
|
||||
inc(c.bufpos)
|
||||
add(tok.literal, ':')
|
||||
of 'e', 'E':
|
||||
if c.buf[c.bufpos + 1] == '\'':
|
||||
of 'e', 'E':
|
||||
if c.buf[c.bufpos + 1] == '\'':
|
||||
inc(c.bufpos)
|
||||
getString(c, tok, tkEscapeConstant)
|
||||
else:
|
||||
else:
|
||||
getSymbol(c, tok)
|
||||
of 'b', 'B':
|
||||
if c.buf[c.bufpos + 1] == '\'':
|
||||
|
|
@ -417,11 +417,11 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
|||
else:
|
||||
getSymbol(c, tok)
|
||||
of '$': getDollarString(c, tok)
|
||||
of '[':
|
||||
of '[':
|
||||
tok.kind = tkBracketLe
|
||||
inc(c.bufpos)
|
||||
add(tok.literal, '[')
|
||||
of ']':
|
||||
of ']':
|
||||
tok.kind = tkBracketRi
|
||||
inc(c.bufpos)
|
||||
add(tok.literal, ']')
|
||||
|
|
@ -433,7 +433,7 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
|||
tok.kind = tkParRi
|
||||
inc(c.bufpos)
|
||||
add(tok.literal, ')')
|
||||
of '.':
|
||||
of '.':
|
||||
if c.buf[c.bufpos + 1] in Digits:
|
||||
getNumeric(c, tok)
|
||||
else:
|
||||
|
|
@ -443,7 +443,7 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
|||
of '0'..'9': getNumeric(c, tok)
|
||||
of '\'': getString(c, tok, tkStringConstant)
|
||||
of '"': getQuotedIdentifier(c, tok)
|
||||
of lexbase.EndOfFile:
|
||||
of lexbase.EndOfFile:
|
||||
tok.kind = tkEof
|
||||
tok.literal = "[EOF]"
|
||||
of 'a', 'c', 'd', 'f'..'w', 'y', 'z', 'A', 'C', 'D', 'F'..'W', 'Y', 'Z', '_',
|
||||
|
|
@ -455,8 +455,8 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
|||
else:
|
||||
add(tok.literal, c.buf[c.bufpos])
|
||||
inc(c.bufpos)
|
||||
|
||||
proc errorStr(L: SqlLexer, msg: string): string =
|
||||
|
||||
proc errorStr(L: SqlLexer, msg: string): string =
|
||||
result = "$1($2, $3) Error: $4" % [L.filename, $getLine(L), $getColumn(L), msg]
|
||||
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ type
|
|||
nkPrimaryKey,
|
||||
nkForeignKey,
|
||||
nkNotNull,
|
||||
|
||||
|
||||
nkStmtList,
|
||||
nkDot,
|
||||
nkDotDot,
|
||||
|
|
@ -530,13 +530,13 @@ type
|
|||
nkValueList,
|
||||
nkWhere,
|
||||
nkCreateTable,
|
||||
nkCreateTableIfNotExists,
|
||||
nkCreateTableIfNotExists,
|
||||
nkCreateType,
|
||||
nkCreateTypeIfNotExists,
|
||||
nkCreateIndex,
|
||||
nkCreateIndexIfNotExists,
|
||||
nkEnumDef
|
||||
|
||||
|
||||
type
|
||||
SqlParseError* = object of ValueError ## Invalid SQL encountered
|
||||
SqlNode* = ref SqlNodeObj ## an SQL abstract syntax tree node
|
||||
|
|
@ -563,11 +563,11 @@ proc newNode(k: SqlNodeKind, s: string): SqlNode =
|
|||
new(result)
|
||||
result.kind = k
|
||||
result.strVal = s
|
||||
|
||||
|
||||
proc len*(n: SqlNode): int =
|
||||
if isNil(n.sons): result = 0
|
||||
else: result = n.sons.len
|
||||
|
||||
|
||||
proc add*(father, n: SqlNode) =
|
||||
if isNil(father.sons): father.sons = @[]
|
||||
add(father.sons, n)
|
||||
|
|
@ -641,11 +641,11 @@ proc parseDataType(p: var SqlParser): SqlNode =
|
|||
getTok(p)
|
||||
eat(p, tkParRi)
|
||||
|
||||
proc getPrecedence(p: SqlParser): int =
|
||||
proc getPrecedence(p: SqlParser): int =
|
||||
if isOpr(p, "*") or isOpr(p, "/") or isOpr(p, "%"):
|
||||
result = 6
|
||||
elif isOpr(p, "+") or isOpr(p, "-"):
|
||||
result = 5
|
||||
result = 5
|
||||
elif isOpr(p, "=") or isOpr(p, "<") or isOpr(p, ">") or isOpr(p, ">=") or
|
||||
isOpr(p, "<=") or isOpr(p, "<>") or isOpr(p, "!=") or isKeyw(p, "is") or
|
||||
isKeyw(p, "like"):
|
||||
|
|
@ -664,7 +664,7 @@ proc parseExpr(p: var SqlParser): SqlNode
|
|||
|
||||
proc identOrLiteral(p: var SqlParser): SqlNode =
|
||||
case p.tok.kind
|
||||
of tkIdentifier, tkQuotedIdentifier:
|
||||
of tkIdentifier, tkQuotedIdentifier:
|
||||
result = newNode(nkIdent, p.tok.literal)
|
||||
getTok(p)
|
||||
of tkStringConstant, tkEscapeConstant, tkDollarQuotedConstant:
|
||||
|
|
@ -686,21 +686,21 @@ proc identOrLiteral(p: var SqlParser): SqlNode =
|
|||
getTok(p)
|
||||
result = parseExpr(p)
|
||||
eat(p, tkParRi)
|
||||
else:
|
||||
else:
|
||||
sqlError(p, "expression expected")
|
||||
getTok(p) # we must consume a token here to prevend endless loops!
|
||||
|
||||
proc primary(p: var SqlParser): SqlNode =
|
||||
if p.tok.kind == tkOperator or isKeyw(p, "not"):
|
||||
proc primary(p: var SqlParser): SqlNode =
|
||||
if p.tok.kind == tkOperator or isKeyw(p, "not"):
|
||||
result = newNode(nkPrefix)
|
||||
result.add(newNode(nkIdent, p.tok.literal))
|
||||
getTok(p)
|
||||
result.add(primary(p))
|
||||
return
|
||||
result = identOrLiteral(p)
|
||||
while true:
|
||||
while true:
|
||||
case p.tok.kind
|
||||
of tkParLe:
|
||||
of tkParLe:
|
||||
var a = result
|
||||
result = newNode(nkCall)
|
||||
result.add(a)
|
||||
|
|
@ -710,7 +710,7 @@ proc primary(p: var SqlParser): SqlNode =
|
|||
if p.tok.kind == tkComma: getTok(p)
|
||||
else: break
|
||||
eat(p, tkParRi)
|
||||
of tkDot:
|
||||
of tkDot:
|
||||
getTok(p)
|
||||
var a = result
|
||||
if p.tok.kind == tkDot:
|
||||
|
|
@ -727,14 +727,14 @@ proc primary(p: var SqlParser): SqlNode =
|
|||
sqlError(p, "identifier expected")
|
||||
getTok(p)
|
||||
else: break
|
||||
|
||||
proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int =
|
||||
|
||||
proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int =
|
||||
var
|
||||
v2, node, opNode: SqlNode
|
||||
v = primary(p) # expand while operators have priorities higher than 'limit'
|
||||
var opPred = getPrecedence(p)
|
||||
result = opPred
|
||||
while opPred > limit:
|
||||
while opPred > limit:
|
||||
node = newNode(nkInfix)
|
||||
opNode = newNode(nkIdent, p.tok.literal)
|
||||
getTok(p)
|
||||
|
|
@ -744,8 +744,8 @@ proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int =
|
|||
node.add(v2)
|
||||
v = node
|
||||
opPred = getPrecedence(p)
|
||||
|
||||
proc parseExpr(p: var SqlParser): SqlNode =
|
||||
|
||||
proc parseExpr(p: var SqlParser): SqlNode =
|
||||
discard lowestExprAux(p, result, - 1)
|
||||
|
||||
proc parseTableName(p: var SqlParser): SqlNode =
|
||||
|
|
@ -765,7 +765,7 @@ proc parseColumnReference(p: var SqlParser): SqlNode =
|
|||
result.add(parseTableName(p))
|
||||
eat(p, tkParRi)
|
||||
|
||||
proc parseCheck(p: var SqlParser): SqlNode =
|
||||
proc parseCheck(p: var SqlParser): SqlNode =
|
||||
getTok(p)
|
||||
result = newNode(nkCheck)
|
||||
result.add(parseExpr(p))
|
||||
|
|
@ -817,9 +817,9 @@ proc parseColumnDef(p: var SqlParser): SqlNode =
|
|||
result.add(newNode(nkIdent, p.tok.literal))
|
||||
getTok(p)
|
||||
result.add(parseDataType(p))
|
||||
parseColumnConstraints(p, result)
|
||||
parseColumnConstraints(p, result)
|
||||
|
||||
proc parseIfNotExists(p: var SqlParser, k: SqlNodeKind): SqlNode =
|
||||
proc parseIfNotExists(p: var SqlParser, k: SqlNodeKind): SqlNode =
|
||||
getTok(p)
|
||||
if isKeyw(p, "if"):
|
||||
getTok(p)
|
||||
|
|
@ -880,7 +880,7 @@ proc parseTableDef(p: var SqlParser): SqlNode =
|
|||
result.add(parseTableConstraint(p))
|
||||
if p.tok.kind != tkComma: break
|
||||
eat(p, tkParRi)
|
||||
|
||||
|
||||
proc parseTypeDef(p: var SqlParser): SqlNode =
|
||||
result = parseIfNotExists(p, nkCreateType)
|
||||
expectIdent(p)
|
||||
|
|
@ -966,7 +966,7 @@ proc parseUpdate(p: var SqlParser): SqlNode =
|
|||
result.add(parseWhere(p))
|
||||
else:
|
||||
result.add(nil)
|
||||
|
||||
|
||||
proc parseDelete(p: var SqlParser): SqlNode =
|
||||
getTok(p)
|
||||
result = newNode(nkDelete)
|
||||
|
|
@ -1018,14 +1018,14 @@ proc parseSelect(p: var SqlParser): SqlNode =
|
|||
while true:
|
||||
getTok(p)
|
||||
h.add(parseExpr(p))
|
||||
if p.tok.kind != tkComma: break
|
||||
if p.tok.kind != tkComma: break
|
||||
result.add(h)
|
||||
if isKeyw(p, "union"):
|
||||
result.add(newNode(nkUnion))
|
||||
getTok(p)
|
||||
elif isKeyw(p, "intersect"):
|
||||
result.add(newNode(nkIntersect))
|
||||
getTok(p)
|
||||
getTok(p)
|
||||
elif isKeyw(p, "except"):
|
||||
result.add(newNode(nkExcept))
|
||||
getTok(p)
|
||||
|
|
@ -1083,7 +1083,7 @@ proc open(p: var SqlParser, input: Stream, filename: string) =
|
|||
p.tok.kind = tkInvalid
|
||||
p.tok.literal = ""
|
||||
getTok(p)
|
||||
|
||||
|
||||
proc parse(p: var SqlParser): SqlNode =
|
||||
## parses the content of `p`'s input stream and returns the SQL AST.
|
||||
## Syntax errors raise an `EInvalidSql` exception.
|
||||
|
|
@ -1094,13 +1094,13 @@ proc parse(p: var SqlParser): SqlNode =
|
|||
result.add(s)
|
||||
if result.len == 1:
|
||||
result = result.sons[0]
|
||||
|
||||
|
||||
proc close(p: var SqlParser) =
|
||||
## closes the parser `p`. The associated input stream is closed too.
|
||||
close(SqlLexer(p))
|
||||
|
||||
proc parseSQL*(input: Stream, filename: string): SqlNode =
|
||||
## parses the SQL from `input` into an AST and returns the AST.
|
||||
## parses the SQL from `input` into an AST and returns the AST.
|
||||
## `filename` is only used for error messages.
|
||||
## Syntax errors raise an `EInvalidSql` exception.
|
||||
var p: SqlParser
|
||||
|
|
@ -1114,7 +1114,7 @@ proc ra(n: SqlNode, s: var string, indent: int)
|
|||
|
||||
proc rs(n: SqlNode, s: var string, indent: int,
|
||||
prefix = "(", suffix = ")",
|
||||
sep = ", ") =
|
||||
sep = ", ") =
|
||||
if n.len > 0:
|
||||
s.add(prefix)
|
||||
for i in 0 .. n.len-1:
|
||||
|
|
@ -1162,7 +1162,7 @@ proc ra(n: SqlNode, s: var string, indent: int) =
|
|||
ra(n.sons[1], s, indent)
|
||||
s.add(')')
|
||||
of nkInfix:
|
||||
s.add('(')
|
||||
s.add('(')
|
||||
ra(n.sons[1], s, indent)
|
||||
s.add(' ')
|
||||
ra(n.sons[0], s, indent)
|
||||
|
|
@ -1207,13 +1207,13 @@ proc ra(n: SqlNode, s: var string, indent: int) =
|
|||
s.add("insert into ")
|
||||
ra(n.sons[0], s, indent)
|
||||
ra(n.sons[1], s, indent)
|
||||
if n.sons[2].kind == nkDefault:
|
||||
if n.sons[2].kind == nkDefault:
|
||||
s.add("default values")
|
||||
else:
|
||||
s.add("\nvalues ")
|
||||
ra(n.sons[2], s, indent)
|
||||
s.add(';')
|
||||
of nkUpdate:
|
||||
of nkUpdate:
|
||||
s.add("update ")
|
||||
ra(n.sons[0], s, indent)
|
||||
s.add(" set ")
|
||||
|
|
@ -1225,7 +1225,7 @@ proc ra(n: SqlNode, s: var string, indent: int) =
|
|||
ra(it, s, indent)
|
||||
ra(n.sons[L-1], s, indent)
|
||||
s.add(';')
|
||||
of nkDelete:
|
||||
of nkDelete:
|
||||
s.add("delete from ")
|
||||
ra(n.sons[0], s, indent)
|
||||
ra(n.sons[1], s, indent)
|
||||
|
|
@ -1237,12 +1237,12 @@ proc ra(n: SqlNode, s: var string, indent: int) =
|
|||
rs(n.sons[0], s, indent, "", "", ", ")
|
||||
for i in 1 .. n.len-1: ra(n.sons[i], s, indent)
|
||||
s.add(';')
|
||||
of nkSelectColumns:
|
||||
of nkSelectColumns:
|
||||
assert(false)
|
||||
of nkAsgn:
|
||||
ra(n.sons[0], s, indent)
|
||||
s.add(" = ")
|
||||
ra(n.sons[1], s, indent)
|
||||
ra(n.sons[1], s, indent)
|
||||
of nkFrom:
|
||||
s.add("\nfrom ")
|
||||
rs(n, s, indent, "", "", ", ")
|
||||
|
|
@ -1306,23 +1306,23 @@ proc ra(n: SqlNode, s: var string, indent: int) =
|
|||
s.add("enum ")
|
||||
rs(n, s, indent)
|
||||
|
||||
# What I want:
|
||||
# What I want:
|
||||
#
|
||||
#select(columns = [T1.all, T2.name],
|
||||
#select(columns = [T1.all, T2.name],
|
||||
# fromm = [T1, T2],
|
||||
# where = T1.name ==. T2.name,
|
||||
# orderby = [name]):
|
||||
#
|
||||
#for row in dbQuery(db, """select x, y, z
|
||||
# from a, b
|
||||
#
|
||||
#for row in dbQuery(db, """select x, y, z
|
||||
# from a, b
|
||||
# where a.name = b.name"""):
|
||||
#
|
||||
#
|
||||
|
||||
#select x, y, z:
|
||||
# fromm: Table1, Table2
|
||||
# where: x.name == y.name
|
||||
#db.select(fromm = [t1, t2], where = t1.name == t2.name):
|
||||
#for x, y, z in db.select(fromm = a, b where = a.name == b.name):
|
||||
#for x, y, z in db.select(fromm = a, b where = a.name == b.name):
|
||||
# writeLine x, y, z
|
||||
|
||||
proc renderSQL*(n: SqlNode): string =
|
||||
|
|
@ -1338,7 +1338,7 @@ when not defined(testing) and isMainModule:
|
|||
happiness happiness
|
||||
);
|
||||
CREATE INDEX table1_attr1 ON table1(attr1);
|
||||
|
||||
|
||||
SELECT * FROM myTab WHERE col1 = 'happy';
|
||||
"""), "stdin")))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue