fix
This commit is contained in:
parent
08d7b5d031
commit
ee5a76fd9d
2 changed files with 196 additions and 396 deletions
|
|
@ -55,6 +55,13 @@ const
|
||||||
";", ":", ",", "(", ")", "[", "]", "."
|
";", ":", ",", "(", ")", "[", "]", "."
|
||||||
]
|
]
|
||||||
|
|
||||||
|
reservedKeywords = @[
|
||||||
|
# statements
|
||||||
|
"select", "from", "where", "group", "limit", "having",
|
||||||
|
# functions
|
||||||
|
"count",
|
||||||
|
]
|
||||||
|
|
||||||
proc open(L: var SqlLexer, input: Stream, filename: string) =
|
proc open(L: var SqlLexer, input: Stream, filename: string) =
|
||||||
lexbase.open(L, input)
|
lexbase.open(L, input)
|
||||||
L.filename = filename
|
L.filename = filename
|
||||||
|
|
@ -274,16 +281,16 @@ proc getSymbol(c: var SqlLexer, tok: var Token) =
|
||||||
c.bufpos = pos
|
c.bufpos = pos
|
||||||
tok.kind = tkIdentifier
|
tok.kind = tkIdentifier
|
||||||
|
|
||||||
proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) =
|
proc getQuotedIdentifier(c: var SqlLexer, tok: var Token, quote='\"') =
|
||||||
var pos = c.bufpos + 1
|
var pos = c.bufpos + 1
|
||||||
var buf = c.buf
|
var buf = c.buf
|
||||||
tok.kind = tkQuotedIdentifier
|
tok.kind = tkQuotedIdentifier
|
||||||
while true:
|
while true:
|
||||||
var ch = buf[pos]
|
var ch = buf[pos]
|
||||||
if ch == '\"':
|
if ch == quote:
|
||||||
if buf[pos+1] == '\"':
|
if buf[pos+1] == quote:
|
||||||
inc(pos, 2)
|
inc(pos, 2)
|
||||||
add(tok.literal, '\"')
|
add(tok.literal, quote)
|
||||||
else:
|
else:
|
||||||
inc(pos)
|
inc(pos)
|
||||||
break
|
break
|
||||||
|
|
@ -442,7 +449,8 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
||||||
add(tok.literal, '.')
|
add(tok.literal, '.')
|
||||||
of '0'..'9': getNumeric(c, tok)
|
of '0'..'9': getNumeric(c, tok)
|
||||||
of '\'': getString(c, tok, tkStringConstant)
|
of '\'': getString(c, tok, tkStringConstant)
|
||||||
of '"': getQuotedIdentifier(c, tok)
|
of '"': getQuotedIdentifier(c, tok, '"')
|
||||||
|
of '`': getQuotedIdentifier(c, tok, '`')
|
||||||
of lexbase.EndOfFile:
|
of lexbase.EndOfFile:
|
||||||
tok.kind = tkEof
|
tok.kind = tkEof
|
||||||
tok.literal = "[EOF]"
|
tok.literal = "[EOF]"
|
||||||
|
|
@ -450,7 +458,7 @@ proc getTok(c: var SqlLexer, tok: var Token) =
|
||||||
'\128'..'\255':
|
'\128'..'\255':
|
||||||
getSymbol(c, tok)
|
getSymbol(c, tok)
|
||||||
of '+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%',
|
of '+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%',
|
||||||
'^', '&', '|', '`', '?':
|
'^', '&', '|', '?':
|
||||||
getOperator(c, tok)
|
getOperator(c, tok)
|
||||||
else:
|
else:
|
||||||
add(tok.literal, c.buf[c.bufpos])
|
add(tok.literal, c.buf[c.bufpos])
|
||||||
|
|
@ -504,6 +512,7 @@ type
|
||||||
nkPrefix,
|
nkPrefix,
|
||||||
nkInfix,
|
nkInfix,
|
||||||
nkCall,
|
nkCall,
|
||||||
|
nkPrGroup,
|
||||||
nkColumnReference,
|
nkColumnReference,
|
||||||
nkReferences,
|
nkReferences,
|
||||||
nkDefault,
|
nkDefault,
|
||||||
|
|
@ -700,7 +709,8 @@ proc identOrLiteral(p: var SqlParser): SqlNode =
|
||||||
getTok(p)
|
getTok(p)
|
||||||
of tkParLe:
|
of tkParLe:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
result = parseExpr(p)
|
result = newNode(nkPrGroup)
|
||||||
|
result.add(parseExpr(p))
|
||||||
eat(p, tkParRi)
|
eat(p, tkParRi)
|
||||||
else:
|
else:
|
||||||
sqlError(p, "expression expected")
|
sqlError(p, "expression expected")
|
||||||
|
|
@ -752,7 +762,7 @@ proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int =
|
||||||
result = opPred
|
result = opPred
|
||||||
while opPred > limit:
|
while opPred > limit:
|
||||||
node = newNode(nkInfix)
|
node = newNode(nkInfix)
|
||||||
opNode = newNode(nkIdent, p.tok.literal)
|
opNode = newNode(nkIdent, p.tok.literal.toLower())
|
||||||
getTok(p)
|
getTok(p)
|
||||||
result = lowestExprAux(p, v2, opPred)
|
result = lowestExprAux(p, v2, opPred)
|
||||||
node.add(opNode)
|
node.add(opNode)
|
||||||
|
|
@ -1112,7 +1122,8 @@ proc parseSelect(p: var SqlParser): SqlNode =
|
||||||
join.add(newNode(nkIdent, ""))
|
join.add(newNode(nkIdent, ""))
|
||||||
getTok(p)
|
getTok(p)
|
||||||
else:
|
else:
|
||||||
join.add(parseExpr(p))
|
join.add(newNode(nkIdent, p.tok.literal.toLower()))
|
||||||
|
getTok(p)
|
||||||
eat(p, "join")
|
eat(p, "join")
|
||||||
join.add(parseFromItem(p))
|
join.add(parseFromItem(p))
|
||||||
eat(p, "on")
|
eat(p, "on")
|
||||||
|
|
@ -1167,8 +1178,6 @@ proc parse(p: var SqlParser): SqlNode =
|
||||||
if p.tok.kind == tkEof:
|
if p.tok.kind == tkEof:
|
||||||
break
|
break
|
||||||
eat(p, tkSemicolon)
|
eat(p, tkSemicolon)
|
||||||
if result.len == 1:
|
|
||||||
result = result.sons[0]
|
|
||||||
|
|
||||||
proc close(p: var SqlParser) =
|
proc close(p: var SqlParser) =
|
||||||
## closes the parser `p`. The associated input stream is closed too.
|
## closes the parser `p`. The associated input stream is closed too.
|
||||||
|
|
@ -1198,44 +1207,25 @@ type
|
||||||
upperCase: bool
|
upperCase: bool
|
||||||
buffer: string
|
buffer: string
|
||||||
|
|
||||||
proc add(s: var SqlWriter, thing: string) =
|
|
||||||
s.buffer.add(thing)
|
|
||||||
|
|
||||||
proc add(s: var SqlWriter, thing: char) =
|
proc add(s: var SqlWriter, thing: char) =
|
||||||
s.buffer.add(thing)
|
s.buffer.add(thing)
|
||||||
|
|
||||||
proc addKeyw(s: var SqlWriter, thing: string) =
|
proc add(s: var SqlWriter, thing: string) =
|
||||||
if s.buffer.len > 0 and s.buffer[^1] notin " ,\L(":
|
if s.buffer.len > 0 and s.buffer[^1] notin {' ', '\L', '(', '.'}:
|
||||||
s.buffer.add(" ")
|
s.buffer.add(" ")
|
||||||
if s.upperCase:
|
|
||||||
s.buffer.add(thing.toUpper())
|
|
||||||
else:
|
|
||||||
s.buffer.add(thing)
|
s.buffer.add(thing)
|
||||||
s.buffer.add(" ")
|
|
||||||
|
|
||||||
proc rm(s: var SqlWriter, chars = " \L,") =
|
proc addKeyw(s: var SqlWriter, thing: string) =
|
||||||
while s.buffer.len > 0 and s.buffer[^1] in chars:
|
var keyw = thing
|
||||||
s.buffer = s.buffer[0..^2]
|
if s.upperCase:
|
||||||
|
keyw = keyw.toUpper()
|
||||||
|
s.add(keyw)
|
||||||
|
|
||||||
proc newLine(s: var SqlWriter) =
|
proc addIden(s: var SqlWriter, thing: string) =
|
||||||
s.rm(" \L")
|
var iden = thing
|
||||||
s.buffer.add("\L")
|
if iden.toLower() in reservedKeywords:
|
||||||
for i in 0..<s.indent:
|
iden = '"' & iden & '"'
|
||||||
s.buffer.add(" ")
|
s.add(iden)
|
||||||
|
|
||||||
template inner(s: var SqlWriter, body: untyped) =
|
|
||||||
inc s.indent
|
|
||||||
s.newLine()
|
|
||||||
body
|
|
||||||
dec s.indent
|
|
||||||
|
|
||||||
template innerKeyw(s: var SqlWriter, keyw: string, body: untyped) =
|
|
||||||
s.newLine()
|
|
||||||
s.addKeyw(keyw)
|
|
||||||
inc s.indent
|
|
||||||
s.newLine()
|
|
||||||
body
|
|
||||||
dec s.indent
|
|
||||||
|
|
||||||
proc ra(n: SqlNode, s: var SqlWriter)
|
proc ra(n: SqlNode, s: var SqlWriter)
|
||||||
|
|
||||||
|
|
@ -1247,17 +1237,30 @@ proc rs(n: SqlNode, s: var SqlWriter, prefix = "(", suffix = ")", sep = ", ") =
|
||||||
ra(n.sons[i], s)
|
ra(n.sons[i], s)
|
||||||
s.add(suffix)
|
s.add(suffix)
|
||||||
|
|
||||||
|
proc addMulti(s: var SqlWriter, n: SqlNode, sep = ',') =
|
||||||
|
if n.len > 0:
|
||||||
|
for i in 0 .. n.len-1:
|
||||||
|
if i > 0: s.add(sep)
|
||||||
|
ra(n.sons[i], s)
|
||||||
|
|
||||||
|
proc addMulti(s: var SqlWriter, n: SqlNode, sep = ',', prefix, suffix: char) =
|
||||||
|
if n.len > 0:
|
||||||
|
s.add(prefix)
|
||||||
|
for i in 0 .. n.len-1:
|
||||||
|
if i > 0: s.add(sep)
|
||||||
|
ra(n.sons[i], s)
|
||||||
|
s.add(suffix)
|
||||||
|
|
||||||
proc ra(n: SqlNode, s: var SqlWriter) =
|
proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkNone: discard
|
of nkNone: discard
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
if allCharsInSet(n.strVal, {'\33'..'\127'}):
|
if allCharsInSet(n.strVal, {'\33'..'\127'}) and n.strVal.toLower() notin reservedKeywords:
|
||||||
s.add(n.strVal)
|
s.add(n.strVal)
|
||||||
else:
|
else:
|
||||||
s.add("\"" & replace(n.strVal, "\"", "\"\"") & "\"")
|
s.add("\"" & replace(n.strVal, "\"", "\"\"") & "\"")
|
||||||
of nkStringLit:
|
of nkStringLit:
|
||||||
# TODO add e'' as an option?
|
|
||||||
s.add(escape(n.strVal, "'", "'"))
|
s.add(escape(n.strVal, "'", "'"))
|
||||||
of nkBitStringLit:
|
of nkBitStringLit:
|
||||||
s.add("b'" & n.strVal & "'")
|
s.add("b'" & n.strVal & "'")
|
||||||
|
|
@ -1277,33 +1280,33 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
s.addKeyw("null")
|
s.addKeyw("null")
|
||||||
of nkDot:
|
of nkDot:
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add(".")
|
s.add('.')
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
of nkDotDot:
|
of nkDotDot:
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add(". .")
|
s.add(". .")
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
of nkPrefix:
|
of nkPrefix:
|
||||||
s.add('(')
|
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add(' ')
|
s.add(' ')
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
s.add(')')
|
|
||||||
of nkInfix:
|
of nkInfix:
|
||||||
s.add('(')
|
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
s.add(' ')
|
s.add(' ')
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add(' ')
|
s.add(' ')
|
||||||
ra(n.sons[2], s)
|
ra(n.sons[2], s)
|
||||||
s.add(')')
|
|
||||||
of nkCall, nkColumnReference:
|
of nkCall, nkColumnReference:
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add('(')
|
s.add('(')
|
||||||
for i in 1..n.len-1:
|
for i in 1..n.len-1:
|
||||||
if i > 1: s.add(", ")
|
if i > 1: s.add(',')
|
||||||
ra(n.sons[i], s)
|
ra(n.sons[i], s)
|
||||||
s.add(')')
|
s.add(')')
|
||||||
|
of nkPrGroup:
|
||||||
|
s.add('(')
|
||||||
|
s.addMulti(n)
|
||||||
|
s.add(')')
|
||||||
of nkReferences:
|
of nkReferences:
|
||||||
s.addKeyw("references")
|
s.addKeyw("references")
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
|
|
@ -1324,29 +1327,25 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
of nkIdentity:
|
of nkIdentity:
|
||||||
s.addKeyw("identity")
|
s.addKeyw("identity")
|
||||||
of nkColumnDef:
|
of nkColumnDef:
|
||||||
s.add("\n ")
|
|
||||||
rs(n, s, "", "", " ")
|
rs(n, s, "", "", " ")
|
||||||
of nkStmtList:
|
of nkStmtList:
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
ra(n.sons[i], s)
|
ra(n.sons[i], s)
|
||||||
s.add("\n")
|
s.add(';')
|
||||||
of nkInsert:
|
of nkInsert:
|
||||||
assert n.len == 3
|
assert n.len == 3
|
||||||
s.addKeyw("insert into")
|
s.addKeyw("insert into")
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add(" ")
|
s.add(' ')
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
if n.sons[2].kind == nkDefault:
|
if n.sons[2].kind == nkDefault:
|
||||||
s.addKeyw("default values")
|
s.addKeyw("default values")
|
||||||
else:
|
else:
|
||||||
s.newLine()
|
|
||||||
ra(n.sons[2], s)
|
ra(n.sons[2], s)
|
||||||
s.rm(" ")
|
|
||||||
s.add(';')
|
|
||||||
of nkUpdate:
|
of nkUpdate:
|
||||||
s.innerKeyw("update"):
|
s.addKeyw("update")
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.innerKeyw("set"):
|
s.addKeyw("set")
|
||||||
var L = n.len
|
var L = n.len
|
||||||
for i in 1 .. L-2:
|
for i in 1 .. L-2:
|
||||||
if i > 1: s.add(", ")
|
if i > 1: s.add(", ")
|
||||||
|
|
@ -1354,25 +1353,17 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
assert it.kind == nkAsgn
|
assert it.kind == nkAsgn
|
||||||
ra(it, s)
|
ra(it, s)
|
||||||
ra(n.sons[L-1], s)
|
ra(n.sons[L-1], s)
|
||||||
s.add(';')
|
|
||||||
of nkDelete:
|
of nkDelete:
|
||||||
s.addKeyw("delete from")
|
s.addKeyw("delete from")
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
s.add(';')
|
|
||||||
of nkSelect, nkSelectDistinct:
|
of nkSelect, nkSelectDistinct:
|
||||||
s.addKeyw("select")
|
s.addKeyw("select")
|
||||||
if n.kind == nkSelectDistinct:
|
if n.kind == nkSelectDistinct:
|
||||||
s.addKeyw("distinct")
|
s.addKeyw("distinct")
|
||||||
s.inner:
|
s.addMulti(n.sons[0])
|
||||||
for son in n.sons[0].sons:
|
|
||||||
ra(son, s)
|
|
||||||
s.add(',')
|
|
||||||
s.newLine()
|
|
||||||
s.rm()
|
|
||||||
for i in 1 .. n.len-1:
|
for i in 1 .. n.len-1:
|
||||||
ra(n.sons[i], s)
|
ra(n.sons[i], s)
|
||||||
s.add(';')
|
|
||||||
of nkSelectColumns:
|
of nkSelectColumns:
|
||||||
assert(false)
|
assert(false)
|
||||||
of nkSelectPair:
|
of nkSelectPair:
|
||||||
|
|
@ -1385,12 +1376,9 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
else:
|
else:
|
||||||
assert n.sons[0].kind == nkSelect
|
assert n.sons[0].kind == nkSelect
|
||||||
s.add("(")
|
s.add('(')
|
||||||
s.inner:
|
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.rm("; \L")
|
s.add(')')
|
||||||
s.newLine()
|
|
||||||
s.add(")")
|
|
||||||
if n.sons.len == 2:
|
if n.sons.len == 2:
|
||||||
s.addKeyw("as")
|
s.addKeyw("as")
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
|
|
@ -1399,29 +1387,29 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
s.add(" = ")
|
s.add(" = ")
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
of nkFrom:
|
of nkFrom:
|
||||||
s.innerKeyw("from"):
|
s.addKeyw("from")
|
||||||
rs(n, s, "", "", ", ")
|
s.addMulti(n)
|
||||||
of nkGroup:
|
of nkGroup:
|
||||||
s.innerKeyw("group by"):
|
s.addKeyw("group by")
|
||||||
rs(n, s, "", "", ", ")
|
s.addMulti(n)
|
||||||
of nkLimit:
|
of nkLimit:
|
||||||
s.innerKeyw("limit"):
|
s.addKeyw("limit")
|
||||||
rs(n, s, "", "", ", ")
|
s.addMulti(n)
|
||||||
of nkHaving:
|
of nkHaving:
|
||||||
s.innerKeyw("having"):
|
s.addKeyw("having")
|
||||||
rs(n, s, "", "", ", ")
|
s.addMulti(n)
|
||||||
of nkOrder:
|
of nkOrder:
|
||||||
s.innerKeyw("order by"):
|
s.addKeyw("order by")
|
||||||
rs(n, s, "", "", ", ")
|
s.addMulti(n)
|
||||||
of nkJoin:
|
of nkJoin:
|
||||||
var joinType = n.sons[0].strVal
|
var joinType = n.sons[0].strVal
|
||||||
if joinType == "":
|
if joinType == "":
|
||||||
joinType = "join"
|
joinType = "join"
|
||||||
else:
|
else:
|
||||||
joinType &= " " & "join"
|
joinType &= " " & "join"
|
||||||
s.innerKeyw(joinType):
|
s.addKeyw(joinType)
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
s.innerKeyw("on"):
|
s.addKeyw("on")
|
||||||
ra(n.sons[2], s)
|
ra(n.sons[2], s)
|
||||||
of nkDesc:
|
of nkDesc:
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
|
|
@ -1438,9 +1426,7 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
s.addKeyw("values")
|
s.addKeyw("values")
|
||||||
rs(n, s)
|
rs(n, s)
|
||||||
of nkWhere:
|
of nkWhere:
|
||||||
s.newLine()
|
|
||||||
s.addKeyw("where")
|
s.addKeyw("where")
|
||||||
s.inner:
|
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
of nkCreateTable, nkCreateTableIfNotExists:
|
of nkCreateTable, nkCreateTableIfNotExists:
|
||||||
s.addKeyw("create table")
|
s.addKeyw("create table")
|
||||||
|
|
@ -1449,7 +1435,7 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.add('(')
|
s.add('(')
|
||||||
for i in 1..n.len-1:
|
for i in 1..n.len-1:
|
||||||
if i > 1: s.add(",")
|
if i > 1: s.add(',')
|
||||||
ra(n.sons[i], s)
|
ra(n.sons[i], s)
|
||||||
s.add(");")
|
s.add(");")
|
||||||
of nkCreateType, nkCreateTypeIfNotExists:
|
of nkCreateType, nkCreateTypeIfNotExists:
|
||||||
|
|
@ -1459,7 +1445,6 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||||
ra(n.sons[0], s)
|
ra(n.sons[0], s)
|
||||||
s.addKeyw("as")
|
s.addKeyw("as")
|
||||||
ra(n.sons[1], s)
|
ra(n.sons[1], s)
|
||||||
s.add(';')
|
|
||||||
of nkCreateIndex, nkCreateIndexIfNotExists:
|
of nkCreateIndex, nkCreateIndexIfNotExists:
|
||||||
s.addKeyw("create index")
|
s.addKeyw("create index")
|
||||||
if n.kind == nkCreateIndexIfNotExists:
|
if n.kind == nkCreateIndexIfNotExists:
|
||||||
|
|
|
||||||
|
|
@ -1,346 +1,149 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tparsesql.nim"
|
file: "tparsesql.nim"
|
||||||
output: '''select
|
|
||||||
foo
|
|
||||||
from
|
|
||||||
table;
|
|
||||||
select
|
|
||||||
foo
|
|
||||||
from
|
|
||||||
table;
|
|
||||||
select
|
|
||||||
foo
|
|
||||||
from
|
|
||||||
table
|
|
||||||
limit
|
|
||||||
10;
|
|
||||||
select
|
|
||||||
foo,
|
|
||||||
bar,
|
|
||||||
baz
|
|
||||||
from
|
|
||||||
table
|
|
||||||
limit
|
|
||||||
10;
|
|
||||||
select
|
|
||||||
foo as bar
|
|
||||||
from
|
|
||||||
table;
|
|
||||||
select
|
|
||||||
foo as foo_prime,
|
|
||||||
bar as bar_prime,
|
|
||||||
baz as baz_prime
|
|
||||||
from
|
|
||||||
table;
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
table;
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
table
|
|
||||||
where
|
|
||||||
((a = b) and (c = d));
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
table
|
|
||||||
where
|
|
||||||
(not b);
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
table
|
|
||||||
where
|
|
||||||
(a and (not b));
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
table
|
|
||||||
where
|
|
||||||
(((a = b) and (c = d)) or ((n is null) and (((not b) + 1) = 3)));
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
table
|
|
||||||
having
|
|
||||||
((a = b) and (c = d));
|
|
||||||
select
|
|
||||||
a,
|
|
||||||
b
|
|
||||||
from
|
|
||||||
table
|
|
||||||
group by
|
|
||||||
a;
|
|
||||||
select
|
|
||||||
a,
|
|
||||||
b
|
|
||||||
from
|
|
||||||
table
|
|
||||||
group by
|
|
||||||
1, 2;
|
|
||||||
select
|
|
||||||
t.a
|
|
||||||
from
|
|
||||||
t as t;
|
|
||||||
select
|
|
||||||
a,
|
|
||||||
b
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
t
|
|
||||||
);
|
|
||||||
select
|
|
||||||
a,
|
|
||||||
b
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
t
|
|
||||||
) as foo;
|
|
||||||
select
|
|
||||||
a,
|
|
||||||
b
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
inner as inner1
|
|
||||||
) as inner2
|
|
||||||
) as inner3
|
|
||||||
) as inner4
|
|
||||||
) as inner5;
|
|
||||||
select
|
|
||||||
a,
|
|
||||||
b
|
|
||||||
from
|
|
||||||
(
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
a
|
|
||||||
), (
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
b
|
|
||||||
), (
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
c
|
|
||||||
);
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
Products
|
|
||||||
where
|
|
||||||
(Price BETWEEN (10 AND 20));
|
|
||||||
select
|
|
||||||
id
|
|
||||||
from
|
|
||||||
a
|
|
||||||
join
|
|
||||||
b
|
|
||||||
on
|
|
||||||
(a.id == b.id);
|
|
||||||
select
|
|
||||||
id
|
|
||||||
from
|
|
||||||
a
|
|
||||||
join
|
|
||||||
(
|
|
||||||
select
|
|
||||||
id
|
|
||||||
from
|
|
||||||
c
|
|
||||||
) as b
|
|
||||||
on
|
|
||||||
(a.id == b.id);
|
|
||||||
select
|
|
||||||
id
|
|
||||||
from
|
|
||||||
a
|
|
||||||
INNER join
|
|
||||||
b
|
|
||||||
on
|
|
||||||
(a.id == b.id);
|
|
||||||
select
|
|
||||||
id
|
|
||||||
from
|
|
||||||
a
|
|
||||||
OUTER join
|
|
||||||
b
|
|
||||||
on
|
|
||||||
(a.id == b.id);
|
|
||||||
select
|
|
||||||
id
|
|
||||||
from
|
|
||||||
a
|
|
||||||
CROSS join
|
|
||||||
b
|
|
||||||
on
|
|
||||||
(a.id == b.id);
|
|
||||||
create type happiness as enum ('happy', 'very happy', 'ecstatic');
|
|
||||||
create table holidays(
|
|
||||||
num_weeks int,
|
|
||||||
happiness happiness);
|
|
||||||
create index table1_attr1 on table1(attr1);
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
myTab
|
|
||||||
where
|
|
||||||
(col1 = 'happy');
|
|
||||||
|
|
||||||
insert into Customers (CustomerName, ContactName, Address, City, PostalCode, Country)
|
|
||||||
values ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway');
|
|
||||||
insert into TableName default values;
|
|
||||||
|
|
||||||
update
|
|
||||||
Customers
|
|
||||||
set
|
|
||||||
ContactName = 'Alfred Schmidt', City = 'Frankfurt'
|
|
||||||
where
|
|
||||||
(CustomerID = 1);
|
|
||||||
delete from table_name;
|
|
||||||
delete from table_name;
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
Customers;
|
|
||||||
select
|
|
||||||
*
|
|
||||||
from
|
|
||||||
Customers
|
|
||||||
where
|
|
||||||
((((CustomerName LIKE 'L%') OR (CustomerName LIKE 'R%')) OR (CustomerName LIKE 'W%')) AND (Country = 'USA'))
|
|
||||||
order by
|
|
||||||
CustomerName;
|
|
||||||
|
|
||||||
'''
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import parsesql
|
import parsesql
|
||||||
|
|
||||||
echo $parseSQL "SELECT foo FROM table;"
|
doAssert $parseSQL("SELECT foo FROM table;") == "select foo from table;"
|
||||||
echo $parseSQL "SELECT foo FROM table"
|
doAssert $parseSQL("""
|
||||||
echo $parseSQL "SELECT foo FROM table limit 10"
|
SELECT
|
||||||
echo $parseSQL "SELECT foo, bar, baz FROM table limit 10"
|
CustomerName,
|
||||||
echo $parseSQL "SELECT foo AS bar FROM table"
|
ContactName,
|
||||||
echo $parseSQL "SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table"
|
Address,
|
||||||
echo $parseSQL "SELECT * FROM table"
|
City,
|
||||||
|
PostalCode,
|
||||||
|
Country,
|
||||||
|
CustomerName,
|
||||||
|
ContactName,
|
||||||
|
Address,
|
||||||
|
City,
|
||||||
|
PostalCode,
|
||||||
|
Country
|
||||||
|
FROM table;""") == "select CustomerName, ContactName, Address, City, PostalCode, Country, CustomerName, ContactName, Address, City, PostalCode, Country from table;"
|
||||||
|
|
||||||
|
doAssert $parseSQL("SELECT foo FROM table limit 10") == "select foo from table limit 10;"
|
||||||
|
doAssert $parseSQL("SELECT foo, bar, baz FROM table limit 10") == "select foo, bar, baz from table limit 10;"
|
||||||
|
doAssert $parseSQL("SELECT foo AS bar FROM table") == "select foo as bar from table;"
|
||||||
|
doAssert $parseSQL("SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table") == "select foo as foo_prime, bar as bar_prime, baz as baz_prime from table;"
|
||||||
|
doAssert $parseSQL("SELECT * FROM table") == "select * from table;"
|
||||||
|
|
||||||
|
|
||||||
#TODO add count(*)
|
#TODO add count(*)
|
||||||
#echo $parseSQL "SELECT COUNT(*) FROM table"
|
#doAssert $parseSQL("SELECT COUNT(*) FROM table"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT * FROM table
|
SELECT * FROM table
|
||||||
WHERE a = b and c = d
|
WHERE a = b and c = d
|
||||||
"""
|
""") == "select * from table where a = b and c = d;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT * FROM table
|
SELECT * FROM table
|
||||||
WHERE not b
|
WHERE not b
|
||||||
"""
|
""") == "select * from table where not b;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT
|
SELECT
|
||||||
*
|
*
|
||||||
FROM
|
FROM
|
||||||
table
|
table
|
||||||
WHERE
|
WHERE
|
||||||
a and not b
|
a and not b
|
||||||
"""
|
""") == "select * from table where a and not b;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT * FROM table
|
SELECT * FROM table
|
||||||
WHERE a = b and c = d or n is null and not b + 1 = 3
|
WHERE a = b and c = d or n is null and not b + 1 = 3
|
||||||
"""
|
""") == "select * from table where a = b and c = d or n is null and not b + 1 = 3;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
|
SELECT * FROM table
|
||||||
|
WHERE (a = b and c = d) or (n is null and not b + 1 = 3)
|
||||||
|
""") == "select * from table where(a = b and c = d) or (n is null and not b + 1 = 3);"
|
||||||
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT * FROM table
|
SELECT * FROM table
|
||||||
HAVING a = b and c = d
|
HAVING a = b and c = d
|
||||||
"""
|
""") == "select * from table having a = b and c = d;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT a, b FROM table
|
SELECT a, b FROM table
|
||||||
GROUP BY a
|
GROUP BY a
|
||||||
"""
|
""") == "select a, b from table group by a;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT a, b FROM table
|
SELECT a, b FROM table
|
||||||
GROUP BY 1, 2
|
GROUP BY 1, 2
|
||||||
"""
|
""") == "select a, b from table group by 1, 2;"
|
||||||
echo $parseSQL "SELECT t.a FROM t as t"
|
|
||||||
echo $parseSQL """
|
doAssert $parseSQL("SELECT t.a FROM t as t") == "select t.a from t as t;"
|
||||||
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT a, b FROM (
|
SELECT a, b FROM (
|
||||||
SELECT * FROM t
|
SELECT * FROM t
|
||||||
)
|
)
|
||||||
"""
|
""") == "select a, b from(select * from t);"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT a, b FROM (
|
SELECT a, b FROM (
|
||||||
SELECT * FROM t
|
SELECT * FROM t
|
||||||
) as foo
|
) as foo
|
||||||
"""
|
""") == "select a, b from(select * from t) as foo;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT a, b FROM (
|
SELECT a, b FROM (
|
||||||
SELECT * FROM (
|
SELECT * FROM (
|
||||||
SELECT * FROM (
|
SELECT * FROM (
|
||||||
SELECT * FROM (
|
SELECT * FROM (
|
||||||
SELECT * FROM inner as inner1
|
SELECT * FROM innerTable as inner1
|
||||||
) as inner2
|
) as inner2
|
||||||
) as inner3
|
) as inner3
|
||||||
) as inner4
|
) as inner4
|
||||||
) as inner5
|
) as inner5
|
||||||
"""
|
""") == "select a, b from(select * from(select * from(select * from(select * from innerTable as inner1) as inner2) as inner3) as inner4) as inner5;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT a, b FROM
|
SELECT a, b FROM
|
||||||
(SELECT * FROM a),
|
(SELECT * FROM a),
|
||||||
(SELECT * FROM b),
|
(SELECT * FROM b),
|
||||||
(SELECT * FROM c)
|
(SELECT * FROM c)
|
||||||
"""
|
""") == "select a, b from(select * from a),(select * from b),(select * from c);"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT * FROM Products
|
SELECT * FROM Products
|
||||||
WHERE Price BETWEEN 10 AND 20;
|
WHERE Price BETWEEN 10 AND 20;
|
||||||
"""
|
""") == "select * from Products where Price between 10 and 20;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT id FROM a
|
SELECT id FROM a
|
||||||
JOIN b
|
JOIN b
|
||||||
ON a.id == b.id
|
ON a.id == b.id
|
||||||
"""
|
""") == "select id from a join b on a.id == b.id;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT id FROM a
|
SELECT id FROM a
|
||||||
JOIN (SELECT id from c) as b
|
JOIN (SELECT id from c) as b
|
||||||
ON a.id == b.id
|
ON a.id == b.id
|
||||||
"""
|
""") == "select id from a join(select id from c) as b on a.id == b.id;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT id FROM a
|
SELECT id FROM a
|
||||||
INNER JOIN b
|
INNER JOIN b
|
||||||
ON a.id == b.id
|
ON a.id == b.id
|
||||||
"""
|
""") == "select id from a inner join b on a.id == b.id;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT id FROM a
|
SELECT id FROM a
|
||||||
OUTER JOIN b
|
OUTER JOIN b
|
||||||
ON a.id == b.id
|
ON a.id == b.id
|
||||||
"""
|
""") == "select id from a outer join b on a.id == b.id;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT id FROM a
|
SELECT id FROM a
|
||||||
CROSS JOIN b
|
CROSS JOIN b
|
||||||
ON a.id == b.id
|
ON a.id == b.id
|
||||||
"""
|
""") == "select id from a cross join b on a.id == b.id;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
|
CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
|
||||||
CREATE TABLE holidays (
|
CREATE TABLE holidays (
|
||||||
num_weeks int,
|
num_weeks int,
|
||||||
|
|
@ -348,29 +151,41 @@ CREATE TABLE holidays (
|
||||||
);
|
);
|
||||||
CREATE INDEX table1_attr1 ON table1(attr1);
|
CREATE INDEX table1_attr1 ON table1(attr1);
|
||||||
SELECT * FROM myTab WHERE col1 = 'happy';
|
SELECT * FROM myTab WHERE col1 = 'happy';
|
||||||
"""
|
""") == "create type happiness as enum ('happy' , 'very happy' , 'ecstatic' ); create table holidays(num_weeks int , happiness happiness );; create index table1_attr1 on table1(attr1 );; select * from myTab where col1 = 'happy';"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country)
|
INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country)
|
||||||
VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway');
|
VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway');
|
||||||
"""
|
""") == "insert into Customers (CustomerName , ContactName , Address , City , PostalCode , Country ) values ('Cardinal' , 'Tom B. Erichsen' , 'Skagen 21' , 'Stavanger' , '4006' , 'Norway' );"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
INSERT INTO TableName DEFAULT VALUES
|
INSERT INTO TableName DEFAULT VALUES
|
||||||
"""
|
""") == "insert into TableName default values;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
UPDATE Customers
|
UPDATE Customers
|
||||||
SET ContactName = 'Alfred Schmidt', City= 'Frankfurt'
|
SET ContactName = 'Alfred Schmidt', City= 'Frankfurt'
|
||||||
WHERE CustomerID = 1;
|
WHERE CustomerID = 1;
|
||||||
"""
|
""") == "update Customers set ContactName = 'Alfred Schmidt' , City = 'Frankfurt' where CustomerID = 1;"
|
||||||
echo $parseSQL "DELETE FROM table_name;"
|
|
||||||
echo $parseSQL "DELETE * FROM table_name;"
|
doAssert $parseSQL("DELETE FROM table_name;") == "delete from table_name;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("DELETE * FROM table_name;") == "delete from table_name;"
|
||||||
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
--Select all:
|
--Select all:
|
||||||
SELECT * FROM Customers;
|
SELECT * FROM Customers;
|
||||||
"""
|
""") == "select * from Customers;"
|
||||||
echo $parseSQL """
|
|
||||||
|
doAssert $parseSQL("""
|
||||||
SELECT * FROM Customers WHERE (CustomerName LIKE 'L%'
|
SELECT * FROM Customers WHERE (CustomerName LIKE 'L%'
|
||||||
OR CustomerName LIKE 'R%' /*OR CustomerName LIKE 'S%'
|
OR CustomerName LIKE 'R%' /*OR CustomerName LIKE 'S%'
|
||||||
OR CustomerName LIKE 'T%'*/ OR CustomerName LIKE 'W%')
|
OR CustomerName LIKE 'T%'*/ OR CustomerName LIKE 'W%')
|
||||||
AND Country='USA'
|
AND Country='USA'
|
||||||
ORDER BY CustomerName;
|
ORDER BY CustomerName;
|
||||||
"""
|
""") == "select * from Customers where(CustomerName like 'L%' or CustomerName like 'R%' or CustomerName like 'W%') and Country = 'USA' order by CustomerName;"
|
||||||
|
|
||||||
|
# parse keywords as identifires
|
||||||
|
doAssert $parseSQL("""
|
||||||
|
SELECT `SELECT`, `FROM` as `GROUP` FROM `WHERE`;
|
||||||
|
""") == """select "SELECT", "FROM" as "GROUP" from "WHERE";"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue