Merge pull request #6156 from PJB3005/SDQL

Fixes arguments inside SDQL call operations being fucked badly.
This commit is contained in:
Rob Nelson
2015-10-15 17:03:31 -07:00
2 changed files with 312 additions and 309 deletions

View File

@@ -87,11 +87,14 @@
var/list/args_list = query_tree["args"]
for(var/datum/d in objs)
var/list/new_args = list()
for(var/arg in args_list)
new_args += SDQL_expression(d, arg)
for(var/v in call_list)
// To stop any procs which sleep from executing slowly.
if(d)
if(hascall(d, v))
spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
spawn() call(d, v)(arglist(new_args)) // Spawn in case the function sleeps.
if("delete")
for(var/datum/d in objs)

View File

@@ -100,347 +100,391 @@
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/SDQL_parser/proc/tokenl() called tick#: [world.time]")
return lowertext(token(i))
/datum/SDQL_parser/proc
//query: select_query | delete_query | update_query
query(i, list/node)
query_type = tokenl(i)
/datum/SDQL_parser/proc/query(i, list/node)
query_type = tokenl(i)
switch(query_type)
if("select")
select_query(i, node)
switch(query_type)
if("select")
select_query(i, node)
if("delete")
delete_query(i, node)
if("delete")
delete_query(i, node)
if("update")
update_query(i, node)
if("update")
update_query(i, node)
if("call")
call_query(i, node)
if("call")
call_query(i, node)
if("explain")
node += "explain"
node["explain"] = list()
query(i + 1, node["explain"])
if("explain")
node += "explain"
node["explain"] = list()
query(i + 1, node["explain"])
// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
select_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
/datum/SDQL_parser/proc/select_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "select"
node["select"] = select
node += "select"
node["select"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
node += "where"
node["where"] = where
return i
return i
//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
delete_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
/datum/SDQL_parser/proc/delete_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "delete"
node["delete"] = select
node += "delete"
node["delete"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
node += "where"
node["where"] = where
return i
return i
//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
update_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
/datum/SDQL_parser/proc/update_query(i, list/node)
var/list/select = list()
i = select_list(i + 1, select)
node += "update"
node["update"] = select
node += "update"
node["update"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
node += "from"
node["from"] = from
if(tokenl(i) != "set")
i = parse_error("UPDATE has misplaced SET")
if(tokenl(i) != "set")
i = parse_error("UPDATE has misplaced SET")
var/list/set_assignments = list()
i = assignments(i + 1, set_assignments)
var/list/set_assignments = list()
i = assignments(i + 1, set_assignments)
node += "set"
node["set"] = set_assignments
node += "set"
node["set"] = set_assignments
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
node += "where"
node["where"] = where
return i
return i
//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
call_query(i, list/node)
var/list/func = list()
var/list/arguments = list()
i = call_function(i + 1, func, arguments)
/datum/SDQL_parser/proc/call_query(i, list/node)
var/list/func = list()
var/list/arguments = list()
i = call_function(i + 1, func, arguments)
node += "call"
node["call"] = func
node["args"] = arguments
if(tokenl(i) != "on")
return i
var/list/select = list()
i = select_list(i + 1, select)
node += "on"
node["on"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
node += "call"
node["call"] = func
node["args"] = arguments
if(tokenl(i) != "on")
return i
var/list/select = list()
i = select_list(i + 1, select)
node += "on"
node["on"] = select
var/list/from = list()
if(tokenl(i) in list("from", "in"))
i = from_list(i + 1, from)
else
from += "world"
node += "from"
node["from"] = from
if(tokenl(i) == "where")
var/list/where = list()
i = bool_expression(i + 1, where)
node += "where"
node["where"] = where
return i
//select_list: select_item [',' select_list]
select_list(i, list/node)
i = select_item(i, node)
/datum/SDQL_parser/proc/select_list(i, list/node)
i = select_item(i, node)
if(token(i) == ",")
i = select_list(i + 1, node)
if(token(i) == ",")
i = select_list(i + 1, node)
return i
return i
//from_list: from_item [',' from_list]
from_list(i, list/node)
i = from_item(i, node)
/datum/SDQL_parser/proc/from_list(i, list/node)
i = from_item(i, node)
if(token(i) == ",")
i = from_list(i + 1, node)
if(token(i) == ",")
i = from_list(i + 1, node)
return i
return i
//assignments: assignment, [',' assignments]
assignments(i, list/node)
i = assignment(i, node)
/datum/SDQL_parser/proc/assignments(i, list/node)
i = assignment(i, node)
if(token(i) == ",")
i = assignments(i + 1, node)
if(token(i) == ",")
i = assignments(i + 1, node)
return i
return i
//select_item: '*' | select_function | object_type
select_item(i, list/node)
/datum/SDQL_parser/proc/select_item(i, list/node)
if(token(i) == "*")
node += "*"
i++
if(token(i) == "*")
node += "*"
i++
else if(tokenl(i) in select_functions)
i = select_function(i, node)
else if(tokenl(i) in select_functions)
i = select_function(i, node)
else
i = object_type(i, node)
else
i = object_type(i, node)
return i
return i
//from_item: 'world' | object_type
from_item(i, list/node)
/datum/SDQL_parser/proc/from_item(i, list/node)
if(token(i) == "world")
node += "world"
i++
if(token(i) == "world")
node += "world"
i++
else
i = object_type(i, node)
else
i = object_type(i, node)
return i
return i
//bool_expression: expression [bool_operator bool_expression]
bool_expression(i, list/node)
/datum/SDQL_parser/proc/bool_expression(i, list/node)
var/list/bool = list()
i = expression(i, bool)
var/list/bool = list()
i = expression(i, bool)
node[++node.len] = bool
node[++node.len] = bool
if(tokenl(i) in boolean_operators)
i = bool_operator(i, node)
i = bool_expression(i, node)
if(tokenl(i) in boolean_operators)
i = bool_operator(i, node)
i = bool_expression(i, node)
return i
return i
//assignment: <variable name> '=' expression
assignment(i, list/node)
/datum/SDQL_parser/proc/assignment(i, list/node)
node += token(i)
node += token(i)
if(token(i + 1) == "=")
var/varname = token(i)
node[varname] = list()
if(token(i + 1) == "=")
var/varname = token(i)
node[varname] = list()
i = expression(i + 2, node[varname])
i = expression(i + 2, node[varname])
else
parse_error("Assignment expected, but no = found")
else
parse_error("Assignment expected, but no = found")
return i
return i
//variable: <variable name> | <variable name> '.' variable
variable(i, list/node)
var/list/L = list(token(i))
node[++node.len] = L
/datum/SDQL_parser/proc/variable(i, list/node)
var/list/L = list(token(i))
node[++node.len] = L
if(token(i + 1) == ".")
L += "."
i = variable(i + 2, L)
if(token(i + 1) == ".")
L += "."
i = variable(i + 2, L)
else
i++
return i
//object_type: <type path> | string
/datum/SDQL_parser/proc/object_type(i, list/node)
if(copytext(token(i), 1, 2) == "/")
node += token(i)
else
i = string(i, node)
return i + 1
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
/datum/SDQL_parser/proc/comparitor(i, list/node)
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//bool_operator: 'AND' | '&&' | 'OR' | '||'
/datum/SDQL_parser/proc/bool_operator(i, list/node)
if(tokenl(i) in list("and", "or", "&&", "||"))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//string: ''' <some text> ''' | '"' <some text > '"'
/datum/SDQL_parser/proc/string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
node += token(i)
else
parse_error("Expected string but found '[token(i)]'")
return i + 1
//call_function: <function name> ['(' [arguments] ')']
/datum/SDQL_parser/proc/call_function(i, list/node, list/arguments)
if(length(tokenl(i)))
node += token(i++)
if(token(i) != "(")
parse_error("Expected ( but found '[token(i)]'")
else if(token(i + 1) != ")")
var/list/temp_expression_list = list()
do
i = expression(i + 1, temp_expression_list)
if(token(i) == ",")
arguments[++arguments.len] = temp_expression_list
temp_expression_list = list()
continue
while(token(i) && token(i) != ")")
arguments[++arguments.len] = temp_expression_list // The code this is copy pasted from won't be executed when it's the last param, this fixes that.
else
i++
else
parse_error("Expected a function but found nothing")
return i + 1
//select_function: count_function
/datum/SDQL_parser/proc/select_function(i, list/node)
parse_error("Sorry, function calls aren't available yet")
return i
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
/datum/SDQL_parser/proc/expression(i, list/node)
if(token(i) in unary_operators)
i = unary_expression(i, node)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
return i
node[++node.len] = expr
else
i = value(i, node)
if(token(i) in binary_operators)
i = binary_operator(i, node)
i = expression(i, node)
else if(token(i) in comparitors)
i = binary_operator(i, node)
var/list/rhs = list()
i = expression(i, rhs)
node[++node.len] = rhs
//object_type: <type path> | string
object_type(i, list/node)
if(copytext(token(i), 1, 2) == "/")
node += token(i)
else
i = string(i, node)
return i + 1
return i
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
comparitor(i, list/node)
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
/datum/SDQL_parser/proc/unary_expression(i, list/node)
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
node += token(i)
if(token(i) in unary_operators)
var/list/unary_exp = list()
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//bool_operator: 'AND' | '&&' | 'OR' | '||'
bool_operator(i, list/node)
if(tokenl(i) in list("and", "or", "&&", "||"))
node += token(i)
else
parse_error("Unknown comparitor [token(i)]")
return i + 1
//string: ''' <some text> ''' | '"' <some text > '"'
string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
node += token(i)
else
parse_error("Expected string but found '[token(i)]'")
return i + 1
//call_function: <function name> ['(' [arguments] ')']
call_function(i, list/node, list/arguments)
if(length(tokenl(i)))
node += token(i++)
if(token(i) != "(")
parse_error("Expected ( but found '[token(i)]'")
else if(token(i + 1) != ")")
do
i = expression(i + 1, arguments)
if(token(i) == ",")
continue
while(token(i) && token(i) != ")")
else
i++
else
parse_error("Expected a function but found nothing")
return i + 1
//select_function: count_function
select_function(i, list/node)
parse_error("Sorry, function calls aren't available yet")
return i
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
expression(i, list/node)
unary_exp += token(i)
i++
if(token(i) in unary_operators)
i = unary_expression(i, node)
i = unary_expression(i, unary_exp)
else if(token(i) == "(")
var/list/expr = list()
@@ -453,94 +497,50 @@
else
i++
node[++node.len] = expr
unary_exp[++unary_exp.len] = expr
else
i = value(i, node)
i = value(i, unary_exp)
if(token(i) in binary_operators)
i = binary_operator(i, node)
i = expression(i, node)
else if(token(i) in comparitors)
i = binary_operator(i, node)
var/list/rhs = list()
i = expression(i, rhs)
node[++node.len] = rhs
node[++node.len] = unary_exp
return i
else
parse_error("Expected unary operator but found '[token(i)]'")
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
unary_expression(i, list/node)
if(token(i) in unary_operators)
var/list/unary_exp = list()
unary_exp += token(i)
i++
if(token(i) in unary_operators)
i = unary_expression(i, unary_exp)
else if(token(i) == "(")
var/list/expr = list()
i = expression(i + 1, expr)
if(token(i) != ")")
parse_error("Missing ) at end of expression.")
else
i++
unary_exp[++unary_exp.len] = expr
else
i = value(i, unary_exp)
node[++node.len] = unary_exp
else
parse_error("Expected unary operator but found '[token(i)]'")
return i
return i
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
binary_operator(i, list/node)
/datum/SDQL_parser/proc/binary_operator(i, list/node)
if(token(i) in (binary_operators + comparitors))
node += token(i)
if(token(i) in (binary_operators + comparitors))
node += token(i)
else
parse_error("Unknown binary operator [token(i)]")
else
parse_error("Unknown binary operator [token(i)]")
return i + 1
return i + 1
//value: variable | string | number | 'null'
value(i, list/node)
/datum/SDQL_parser/proc/value(i, list/node)
if(token(i) == "null")
node += "null"
i++
if(token(i) == "null")
node += "null"
i++
else if(isnum(text2num(token(i))))
node += text2num(token(i))
i++
else if(isnum(text2num(token(i))))
node += text2num(token(i))
i++
else if(copytext(token(i), 1, 2) in list("'", "\""))
i = string(i, node)
else if(copytext(token(i), 1, 2) in list("'", "\""))
i = string(i, node)
else
i = variable(i, node)
else
i = variable(i, node)
return i
return i