Skip to content

Commit

Permalink
Create assignment = built-in operator.
Browse files Browse the repository at this point in the history
  • Loading branch information
EvgSkv committed May 13, 2023
1 parent 42df17a commit aadd0e8
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 4 deletions.
1 change: 1 addition & 0 deletions compiler/dialect_libraries/bq_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

library = """
->(left:, right:) = {arg: left, value: right};
`=`(left:, right:) = right :- left == right;
# All ORDER BY arguments are wrapped, to avoid confusion with
# column index.
Expand Down
1 change: 1 addition & 0 deletions compiler/dialect_libraries/presto_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

library = """
->(left:, right:) = {arg: left, value: right};
`=`(left:, right:) = right :- left == right;
ArgMin(a) = SqlExpr("(ARRAY_AGG({arg} order by {value}))[1]",
{arg: a.arg, value: a.value});
Expand Down
1 change: 1 addition & 0 deletions compiler/dialect_libraries/psql_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

library = """
->(left:, right:) = {arg: left, value: right};
`=`(left:, right:) = right :- left == right;
ArgMin(a) = SqlExpr("(ARRAY_AGG({arg} order by {value}))[1]",
{arg: a.arg, value: a.value});
Expand Down
1 change: 1 addition & 0 deletions compiler/dialect_libraries/sqlite_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

library = """
->(left:, right:) = {arg: left, value: right};
`=`(left:, right:) = right :- left == right;
Arrow(left, right) = arrow :-
left == arrow.arg,
Expand Down
1 change: 1 addition & 0 deletions compiler/dialect_libraries/trino_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

library = """
->(left:, right:) = {arg: left, value: right};
`=`(left:, right:) = right :- left == right;
ArgMin(a) = SqlExpr("(ARRAY_AGG({arg} order by {value}))[1]",
{arg: a.arg, value: a.value});
Expand Down
1 change: 1 addition & 0 deletions integration_tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def RunAll(test_presto=False, test_trino=False):
RunTest("rec_small_cycle_test")
RunTest("rec_cycle_test")

RunTest("sqlite_assignment_test")
RunTest("sqlite_unwrapping_test")
RunTest("sqlite_array_sub_test")
RunTest("sqlite_combine_test")
Expand Down
44 changes: 44 additions & 0 deletions integration_tests/sqlite_assignment_test.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

@Engine("sqlite");

StoreItem(name: "apple", price: 2.0);
StoreItem(name: "banana", price: 1.0);
StoreItem(name: "orange", price: 1.5);
StoreItem(name: "pear", price: 3.0);

PercentageDiscout(item_name: "apple", percentage: 10);
PercentageDiscout(item_name: "orange", percentage: 20);

CustomerPurchase(customer_name: "John", item_name: "apple", quantity: 2);
CustomerPurchase(customer_name: "John", item_name: "banana", quantity: 1);
CustomerPurchase(customer_name: "John", item_name: "orange", quantity: 3);
CustomerPurchase(customer_name: "John", item_name: "orange", quantity: 3);
CustomerPurchase(customer_name: "Jane", item_name: "pear", quantity: 1);
CustomerPurchase(customer_name: "Jane", item_name: "banana", quantity: 2);
CustomerPurchase(customer_name: "Jane", item_name: "apple", quantity: 2);

@OrderBy(CustomerSavings, "customer_name");
CustomerSavings(customer_name:,
total_savings? += savings,
max_fraction? Max= (fraction_savings = percentage / 100.0)) distinct :-
CustomerPurchase(customer_name:, item_name:, quantity:),
PercentageDiscout(item_name:),
StoreItem(name: item_name, price:),
PercentageDiscout(item_name:, percentage:),
savings = price * fraction_savings * quantity;

Test := CustomerSavings();
6 changes: 6 additions & 0 deletions integration_tests/sqlite_assignment_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+---------------+---------------+--------------+
| customer_name | total_savings | max_fraction |
+---------------+---------------+--------------+
| Jane | 0.4 | 0.1 |
| John | 2.2 | 0.2 |
+---------------+---------------+--------------+
6 changes: 3 additions & 3 deletions integration_tests/sqlite_file_test.l
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
@Engine("sqlite");

Test(result) :-
filename == "/tmp/sqlite_file_test_data.txt",
filename = "/tmp/sqlite_file_test_data.txt",
WriteFile(filename, content: input_array) == "OK",
input_array List= (x * 2 :- x in Range(10)),
read_data == ReadJson(filename),
read_data = ReadJson(filename),
result_array List= (x :- x in read_data, x > 10),
result == Join(result_array, "/");
result = Join(result_array, "/");
9 changes: 8 additions & 1 deletion parser_py/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ def ParseLiteral(s):
def ParseInfix(s, operators=None):
"""Parses an infix operator expression."""
operators = operators or [
'||', '&&', '->', '==', '<=', '>=', '<', '>', '!=',
'||', '&&', '->', '==', '<=', '>=', '<', '>', '!=', '=',
' in ', '++?', '++', '+', '-', '*', '/', '%', '^', '!']
unary_operators = ['-', '!']
for op in operators:
Expand Down Expand Up @@ -671,6 +671,10 @@ def ParseConciseCombine(s: HeritageAwareString):
prohibited_operators = ['!', '<', '>']
if operator in prohibited_operators:
return None
# Lowercase operators are not allowed and it would most likely mean
# that user forgot comma before assignment.
if operator[0].islower():
return None
left_expr = ParseExpression(lhs)
_, expression_body = SplitInOneOrTwo(combine, ':-')
if expression_body:
Expand Down Expand Up @@ -786,6 +790,9 @@ def ParseGenericCall(s, opening, closing):
if (s[idx] == opening and
s[-1] == closing and
IsWhole(s[idx + 1:-1])):
# Specialcasing `=` assignment operator for definition.
if predicate == '`=`':
predicate = '='
return predicate, s[idx + 1: -1]


Expand Down

0 comments on commit aadd0e8

Please sign in to comment.