Support mod operator and order-by column alias
@@ -21,6 +21,8 @@ pp = pprint.PrettyPrinter(indent=4)
### TO DO:
# - support parameters in lists, maybe positional parameters $0, $1,...
+# - intelligent interpretation of ^ and $ when regex-matching to string literals?
+# - one can use kgtk_unstringify first to get to the text content
# - allow |-alternatives in relationship and node patterns (the latter being an
# extension to Cypher)
# - more intelligent index creation
@@ -355,7 +357,7 @@ class KgtkQuery(object):
self.pattern_props_to_sql(rel, graph, idcol, litmap, varmap, restrictions, joins)
OPERATOR_TABLE = {
- parser.Add: '+', parser.Sub: '-', parser.Multi: '*', parser.Div: '/',
+ parser.Add: '+', parser.Sub: '-', parser.Multi: '*', parser.Div: '/', parser.Mod: '%',
parser.Eq: '=', parser.Neq: '!=', parser.Lt: '<', parser.Gt: '>',
parser.Lte: '<=', parser.Gte: '>=',
parser.Not: 'NOT', parser.And: 'AND', parser.Or: 'OR',
@@ -387,6 +389,10 @@ class KgtkQuery(object):
if sql_vars is None:
raise Exception('Undefined variable: %s' % query_var)
graph, col = list(sql_vars)[0]
+ if graph == '_':
+ # we have a return column alias:
+ return sql_quote_ident(col)
+ else:
return '%s.%s' % (graph, sql_quote_ident(col))
elif expr_type == parser.List:
@@ -397,7 +403,7 @@ class KgtkQuery(object):
elif expr_type == parser.Minus:
arg = self.expression_to_sql(expr.arg, litmap, varmap)
return '(- %s)' % arg
- elif expr_type in (parser.Add, parser.Sub, parser.Multi, parser.Div):
+ elif expr_type in (parser.Add, parser.Sub, parser.Multi, parser.Div, parser.Mod):
arg1 = self.expression_to_sql(expr.arg1, litmap, varmap)
arg2 = self.expression_to_sql(expr.arg2, litmap, varmap)
op = self.OPERATOR_TABLE[expr_type]
@@ -498,6 +504,9 @@ class KgtkQuery(object):
is_agg = parser.has_element(
item.expression, lambda x: isinstance(x, parser.Call) and self.store.is_aggregate_function(x.function))
if item.name is not None:
+ # we have to register the alias as a variable, otherwise it can't be referenced in --order-by,
+ # but it is not tied to a specific graph table, thus that part is '_' in the registration below:
+ self.register_clause_variable(item.name, ('_', item.name), varmap, set())
select += ' ' + sql_quote_ident(item.name)
agg_info.append(not is_agg and item.name or None)
else:
