diff --git a/.travis.yml b/.travis.yml index 20d628d..d8f4fe7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: install: - pip install mypy - pip install xtermcolor + - pip install typedload script: - make mypy diff --git a/CHANGELOG b/CHANGELOG index 8e2454e..649b8e3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,7 @@ 3.0 +- By default relations are saved as json. This allows to keep the type +- Dates can no longer be added or subtracted +- Types are now inferred by column, no longer by cell - Relations now use frozenset internally and are immutable - Refactored parser to use better typing - Refactored and fixed some optimizations diff --git a/debian/control b/debian/control index d18b47f..6dc6df2 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: math Priority: optional Maintainer: Salvo 'LtWorf' Tomaselli Build-Depends: debhelper-compat (= 13), debhelper (>= 13), python3, dh-python, python3-xtermcolor, pyqt5-dev-tools, - python3-distutils + python3-distutils, python3-typedload Standards-Version: 4.5.0 X-Python3-Version: >= 3.8 Homepage: https://ltworf.github.io/relational/ @@ -12,7 +12,7 @@ Rules-Requires-Root: no Package: python3-relational Architecture: all Section: python -Depends: ${misc:Depends}, ${python3:Depends} +Depends: ${misc:Depends}, ${python3:Depends}, python3-typedload Description: Educational tool for relational algebra (standalone module) Relational is primarily a tool to provide a workspace for experimenting with relational algebra, an offshoot of first-order logic. diff --git a/driver.py b/driver.py index df92aa2..19f8d06 100755 --- a/driver.py +++ b/driver.py @@ -57,7 +57,7 @@ def load_relations(): print ("Loading relation %s with name %s..." % (i, relname)) - rels[relname] = relation.Relation.load('%s%s' % (examples_path, i)) + rels[relname] = relation.Relation.load_csv('%s%s' % (examples_path, i)) print('done') diff --git a/relational/maintenance.py b/relational/maintenance.py index 5afa527..954438a 100644 --- a/relational/maintenance.py +++ b/relational/maintenance.py @@ -1,5 +1,5 @@ # Relational -# Copyright (C) 2008-2017 Salvo "LtWorf" Tomaselli +# Copyright (C) 2008-2020 Salvo "LtWorf" Tomaselli # # Relation is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -90,8 +90,15 @@ class UserInterface: def load(self, filename: str, name: str) -> None: '''Loads a relation from file, and gives it a name to - be used in subsequent queries.''' - rel = Relation.load(filename) + be used in subsequent queries. + + Files ending with .csv are loaded as csv, the others are + loaded as json. + ''' + if filename.endswith('.csv'): + rel = Relation.load_csv(filename) + else: + rel = Relation.load(filename) self.set_relation(name, rel) def unload(self, name: str) -> None: @@ -100,7 +107,10 @@ class UserInterface: def store(self, filename: str, name: str) -> None: '''Stores a relation to file.''' - raise Exception('Not implemented') + if filename.endswith('.csv'): + self.relations[name].save_csv(filename) + else: + self.relations[name].save(filename) def session_dump(self, filename: Optional[str] = None) -> Optional[str]: ''' @@ -161,8 +171,12 @@ class UserInterface: if len(name) == 0: return None - if (name.endswith(".csv")): # removes the extension - name = name[:-4] + # Removing the extension + try: + pos = name.rindex('.') + except ValueError: + return None + name = name[:pos] if not is_valid_relation_name(name): return None diff --git a/relational/relation.py b/relational/relation.py index 8c8d1a6..b20e8e4 100644 --- a/relational/relation.py +++ b/relational/relation.py @@ -19,10 +19,10 @@ # This module provides a classes to represent relations and to perform # relational operations on them. -import csv from itertools import chain, repeat, product as iproduct from collections import deque -from typing import * +from typing import FrozenSet, Iterable, List, Dict, Tuple, Optional +from dataclasses import dataclass from pathlib import Path from relational.rtypes import * @@ -33,8 +33,8 @@ __all__ = [ 'Header', ] - -class Relation(NamedTuple): +@dataclass(repr=True, unsafe_hash=False, frozen=True) +class Relation: ''' This object defines a relation (as a group of consistent tuples) and operations. @@ -58,47 +58,57 @@ class Relation(NamedTuple): method. ''' header: 'Header' - content: FrozenSet[Tuple[Rstring, ...]] + content: FrozenSet[Tuple[CastValue, ...]] @staticmethod - def load(filename: Union[str, Path]) -> 'Relation': + def load_csv(filename: Union[str, Path]) -> 'Relation': ''' Load a relation object from a csv file. The 1st row is the header and the other rows are the content. + + Types will be inferred automatically ''' + import csv with open(filename) as fp: reader = csv.reader(fp) # Creating a csv reader header = Header(next(reader)) # read 1st line return Relation.create_from(header, reader) @staticmethod - def create_from(header: Iterable[str], content: Iterable[Iterable[str]]) -> 'Relation': + def load(filename: Union[str, Path]) -> 'Relation': ''' - Iterator for the header, and iterator for the content. + Load a relation object from a json file. ''' - header = Header(header) - r_content: List[Tuple[Rstring, ...]] = [] - for row in content: - content_row: Tuple[Rstring, ...] = tuple(Rstring(i) for i in row) - if len(content_row) != len(header): - raise ValueError(f'Line {row} contains an incorrect amount of values') - r_content.append(content_row) - return Relation(header, frozenset(r_content)) - - - def __iter__(self): - return iter(self.content) - - def __contains__(self, key): - return key in self.content + with open(filename) as fp: + from json import load as jload + from typedload import load + loaded = jload(fp) + header = Header(loaded['header']) + content = [] + for row in loaded['content']: + if len(row) != len(header): + raise ValueError(f'Line {row} contains an incorrect amount of values') + t_row: Tuple[Optional[Union[int, float, str, Rdate]], ...] = load(row, Tuple[Optional[Union[int, float, str, Rdate]], ...]) # type: ignore + content.append(t_row) + return Relation(header, frozenset(content)) def save(self, filename: Union[Path, str]) -> None: + ''' + Saves the relation in a file. + Will save using the json format + ''' + with open(filename, 'w') as fp: + from json import dump as jdump + from typedload import dump + jdump(dump(self), fp) + + def save_csv(self, filename: Union[Path, str]) -> None: ''' Saves the relation in a file. Will save using the csv format as defined in RFC4180. ''' - + import csv with open(filename, 'w') as fp: writer = csv.writer(fp) # Creating csv writer @@ -109,6 +119,40 @@ class Relation(NamedTuple): # Writing content, already in the correct format writer.writerows(self.content) + @staticmethod + def create_from(header: Iterable[str], content: Iterable[List[str]]) -> 'Relation': + ''' + Iterator for the header, and iterator for the content. + + This will infer types. + ''' + header = Header(header) + r_content = [] + guessed_types = list(repeat({Rdate, float, int, str}, len(header))) + + for row in content: + if len(row) != len(header): + raise ValueError(f'Line {row} contains an incorrect amount of values') + r_content.append(row) + + # Guess types + for i, value in enumerate(row): + guessed_types[i] = guessed_types[i].intersection(guess_type(value)) + + typed_content = [] + for r in r_content: + t = tuple(cast(v, guessed_types[i]) for i, v in enumerate(r)) + typed_content.append(t) + + return Relation(header, frozenset(typed_content)) + + + def __iter__(self): + return iter(self.content) + + def __contains__(self, key): + return key in self.content + def _rearrange(self, other: 'Relation') -> 'Relation': '''If two relations share the same attributes in a different order, this method will use projection to make them have the same attributes' order. @@ -129,8 +173,6 @@ class Relation(NamedTuple): ''' Selection, expr must be a valid Python expression; can contain field names. ''' - header = Header(self.header) - try: c_expr = compile(expr, 'selection', 'eval') except: @@ -139,7 +181,7 @@ class Relation(NamedTuple): content = [] for i in self.content: # Fills the attributes dictionary with the values of the tuple - attributes = {attr: i[j].autocast() + attributes = {attr: i[j] for j, attr in enumerate(self.header) } @@ -147,8 +189,8 @@ class Relation(NamedTuple): if eval(c_expr, attributes): content.append(i) except Exception as e: - raise Exception(f'Failed to evaluate {expr}\n{e}') - return Relation(header, frozenset(content)) + raise Exception(f'Failed to evaluate {expr} with {attributes}\n{e}') + return Relation(self.header, frozenset(content)) def product(self, other: 'Relation') -> 'Relation': ''' @@ -267,9 +309,7 @@ class Relation(NamedTuple): def outer_right(self, other: 'Relation') -> 'Relation': ''' Outer right join. Considers self as left and param as right. If the - tuple has no corrispondence, empy attributes are filled with a "---" - string. This is due to the fact that the None token would cause - problems when saving and reloading the relation. + tuple has no corrispondence, empy attributes are filled with a None. Just like natural join, it works considering shared attributes. ''' return other.outer_left(self) @@ -278,7 +318,6 @@ class Relation(NamedTuple): ''' See documentation for outer_right ''' - shared = self.header.intersection(other.header) # Creating the header with all the fields, done like that because order is @@ -310,7 +349,7 @@ class Relation(NamedTuple): added = True # If it didn't partecipate, adds it if not added: - item = chain(i, repeat(Rstring('---'), len(noid))) + item = chain(i, repeat(None, len(noid))) content.append(tuple(item)) return Relation(header, frozenset(content)) @@ -373,18 +412,18 @@ class Relation(NamedTuple): m_len = [len(i) for i in self.header] # Maximum lenght string for f in self.content: - for col, i in enumerate(f): + for col, i in enumerate(str(val) for val in f): if len(i) > m_len[col]: m_len[col] = len(i) res = "" for f, attr in enumerate(self.header): - res += "%s" % (attr.ljust(2 + m_len[f])) + res += attr.ljust(2 + m_len[f]) for r in self.content: res += "\n" - for col, i in enumerate(r): - res += "%s" % (i.ljust(2 + m_len[col])) + for col, i in enumerate(str(val) for val in r): + res += i.ljust(2 + m_len[col]) return res diff --git a/relational/rtypes.py b/relational/rtypes.py index 1bc4970..29f9aae 100644 --- a/relational/rtypes.py +++ b/relational/rtypes.py @@ -23,124 +23,76 @@ import datetime import keyword import re -from typing import Union +from typing import Union, Set, Any, Callable, Type, Optional +from dataclasses import dataclass + RELATION_NAME_REGEXP = re.compile(r'^[_a-z][_a-z0-9]*$', re.IGNORECASE) - - -class Rstring(str): - - '''String subclass with some custom methods''' - - int_regexp = re.compile(r'^[\+\-]{0,1}[0-9]+$') - float_regexp = re.compile(r'^[\+\-]{0,1}[0-9]+(\.([0-9])+)?$') - date_regexp = re.compile( +_date_regexp = re.compile( r'^([0-9]{1,4})(\\|-|/)([0-9]{1,2})(\\|-|/)([0-9]{1,2})$' ) - - def autocast(self) -> Union[int, float, 'Rdate', 'Rstring']: - ''' - Returns the automatic cast for this - value. - ''' - try: - return self._autocast - except: - pass - - self._autocast = self # type: Union[int, float, 'Rdate', 'Rstring'] - if len(self) > 0: - if self.isInt(): - self._autocast = int(self) - elif self.isFloat(): - self._autocast = float(self) - elif self.isDate(): - self._autocast = Rdate(self) - return self._autocast - - def isInt(self) -> bool: - '''Returns true if the string represents an int number - it only considers as int numbers the strings matching - the following regexp: - r'^[\+\-]{0,1}[0-9]+$' - ''' - return Rstring.int_regexp.match(self) is not None - - def isFloat(self) -> bool: - '''Returns true if the string represents a float number - it only considers as float numbers, the strings matching - the following regexp: - r'^[\+\-]{0,1}[0-9]+(\.([0-9])+)?$' - ''' - return Rstring.float_regexp.match(self) is not None - - def isDate(self) -> bool: - '''Returns true if the string represents a date, - in the format YYYY-MM-DD. as separators '-' , '\', '/' are allowed. - As side-effect, the date object will be stored for future usage, so - no more parsings are needed - ''' - try: - return self._isdate # type: ignore - except: - pass - - r = Rstring.date_regexp.match(self) - if r is None: - self._isdate = False - self._date = None - return False - - try: # Any of the following operations can generate an exception, if it happens, we aren't dealing with a date - year = int(r.group(1)) - month = int(r.group(3)) - day = int(r.group(5)) - d = datetime.date(year, month, day) - self._isdate = True - self._date = d - return True - except: - self._isdate = False - self._date = None - return False - - def getDate(self): - '''Returns the datetime.date object or None''' - try: - return self._date - except: - self.isDate() - return self._date +CastValue = Optional[Union[str, int, float, 'Rdate']] -class Rdate (object): +def guess_type(value: str) -> Set[Union[Callable[[Any], Any], Type['Rdate']]]: + r: Set[Union[Callable[[Any], Any], Type['Rdate']]] = {str} + if _date_regexp.match(value) is not None: + r.add(Rdate) + try: + int(value) + r.add(int) + except ValueError: + pass + + try: + float(value) + r.add(float) + except ValueError: + pass + return r + + +def cast(value: str, guesses: Set) -> CastValue: + if int in guesses: + return int(value) + if Rdate in guesses: + return Rdate.create(value) + if float in guesses: + return float(value) + return value + + +@dataclass(frozen=True) +class Rdate: '''Represents a date''' + year: int + month: int + day: int - def __init__(self, date): - '''date: A string representing a date''' - if not isinstance(date, Rstring): - date = Rstring(date) + @property + def intdate(self) -> datetime.date: + return datetime.date(self.year, self.month, self.day) - self.intdate = date.getDate() - self.day = self.intdate.day - self.month = self.intdate.month - self.weekday = self.intdate.weekday() - self.year = self.intdate.year + @property + def weekday(self) -> int: + return self.intdate.weekday() - def __hash__(self): - return self.intdate.__hash__() + @staticmethod + def create(date: str) -> 'Rdate': + '''date: A string representing a date YYYY-MM-DD''' + r = _date_regexp.match(date) + if not r: + raise ValueError(f'{date} is not a valid date') + + year = int(r.group(1)) + month = int(r.group(3)) + day = int(r.group(5)) + return Rdate(year, month, day) def __str__(self): return self.intdate.__str__() - def __add__(self, days): - res = self.intdate + datetime.timedelta(days) - return Rdate(res.__str__()) - - def __eq__(self, other): - return self.intdate == other.intdate - def __ge__(self, other): return self.intdate >= other.intdate @@ -153,12 +105,6 @@ class Rdate (object): def __lt__(self, other): return self.intdate < other.intdate - def __ne__(self, other): - return self.intdate != other.intdate - - def __sub__(self, other): - return (self.intdate - other.intdate).days - def is_valid_relation_name(name: str) -> bool: '''Checks if a name is valid for a relation. diff --git a/relational_gui/creator.py b/relational_gui/creator.py index 412cd22..42b87f5 100644 --- a/relational_gui/creator.py +++ b/relational_gui/creator.py @@ -1,5 +1,5 @@ # Relational -# Copyright (C) 2008-2015 Salvo "LtWorf" Tomaselli +# Copyright (C) 2008-2020 Salvo "LtWorf" Tomaselli # # Relational is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -52,13 +52,13 @@ class creatorForm(QtWidgets.QDialog): for i in rel.content: self.table.insertRow(self.table.rowCount()) - for j in range(len(i)): + for j, value in enumerate(i): + if value is None: + raise Exception('Relation contains a None value and cannot be edited from the GUI') item = QtWidgets.QTableWidgetItem() - item.setText(i[j]) + item.setText(str(value)) self.table.setItem(self.table.rowCount() - 1, j, item) - pass - def setup_empty(self): self.table.insertColumn(0) self.table.insertColumn(0) @@ -142,11 +142,3 @@ def edit_relation(rel=None): Form.exec_() return Form.result_relation - - -if __name__ == '__main__': - import sys - app = QtGui.QApplication(sys.argv) - r = relation.relation( - "/home/salvo/dev/relational/trunk/samples/people.csv") - print (edit_relation(r)) diff --git a/relational_gui/guihandler.py b/relational_gui/guihandler.py index da34184..b590126 100644 --- a/relational_gui/guihandler.py +++ b/relational_gui/guihandler.py @@ -249,7 +249,13 @@ class relForm(QtWidgets.QMainWindow): for i in rel.content: item = QtWidgets.QTreeWidgetItem() for j,k in enumerate(i): - item.setText(j, k) + if k is None: + item.setBackground(j, QtGui.QBrush(QtCore.Qt.darkRed, QtCore.Qt.Dense4Pattern)) + elif isinstance(k, (int, float)): + item.setForeground(j, QtGui.QPalette().link()) + elif not isinstance(k, str): + item.setForeground(j, QtGui.QPalette().brightText()) + item.setText(j, str(k)) self.ui.table.addTopLevelItem(item) # Sets columns @@ -286,13 +292,13 @@ class relForm(QtWidgets.QMainWindow): filename = QtWidgets.QFileDialog.getSaveFileName( self, QtWidgets.QApplication.translate("Form", "Save Relation"), "", - QtWidgets.QApplication.translate("Form", "Relations (*.csv)") + QtWidgets.QApplication.translate("Form", "Json relations (*.json);;CSV relations (*.csv)") )[0] if (len(filename) == 0): # Returns if no file was selected return relname = self.ui.lstRelations.selectedItems()[0].text() - self.user_interface.relations[relname].save(filename) + self.user_interface.store(filename, relname) def unloadRelation(self): for i in self.ui.lstRelations.selectedItems(): @@ -306,9 +312,15 @@ class relForm(QtWidgets.QMainWindow): def editRelation(self): from relational_gui import creator for i in self.ui.lstRelations.selectedItems(): - result = creator.edit_relation( - self.user_interface.get_relation(i.text()) - ) + try: + result = creator.edit_relation( + self.user_interface.get_relation(i.text()) + ) + except Exception as e: + QtWidgets.QMessageBox.warning( + self, QtWidgets.QApplication.translate("Form", "Error"), str(e) + ) + return if result != None: self.user_interface.set_relation(i.text(), result) self.updateRelations() @@ -410,7 +422,7 @@ class relForm(QtWidgets.QMainWindow): "", QtWidgets.QApplication.translate( "Form", - "Relations (*.csv);;Text Files (*.txt);;All Files (*)" + "Relations (*.json *.csv);;Text Files (*.txt);;All Files (*)" ) ) filenames = f[0] diff --git a/relational_readline/linegui.py b/relational_readline/linegui.py index 8655cac..6471bc3 100644 --- a/relational_readline/linegui.py +++ b/relational_readline/linegui.py @@ -106,8 +106,7 @@ class SimpleCompleter: repr(text), state, repr(response)) return response - -relations = {} +ui = maintenance.UserInterface() completer = SimpleCompleter( ['SURVEY', 'LIST', 'LOAD ', 'UNLOAD ', 'HELP ', 'QUIT', 'SAVE ', '_PRODUCT ', '_UNION ', '_INTERSECTION ', '_DIFFERENCE ', '_JOIN ', '_LJOIN ', '_RJOIN ', '_FJOIN ', '_PROJECTION ', '_RENAME_TO ', '_SELECTION ', '_RENAME ', '_DIVISION ']) @@ -137,7 +136,7 @@ def load_relation(filename: str, defname: Optional[str]) -> Optional[str]: "%s is not a valid relation name" % defname, ERROR_COLOR), file=sys.stderr) return None try: - relations[defname] = relation.Relation.load(filename) + ui.load(filename, defname) completer.add_completion(defname) printtty(colorize("Loaded relation %s" % defname, COLOR_GREEN)) @@ -204,7 +203,7 @@ def exec_line(command: str) -> None: elif command.startswith('HELP'): help(command) elif command == 'LIST': # Lists all the loaded relations - for i in relations: + for i in ui.relations: if not i.startswith('_'): print(i) elif command == 'SURVEY': @@ -225,9 +224,10 @@ def exec_line(command: str) -> None: pars = command.split(' ') if len(pars) < 2: print(colorize("Missing parameter", ERROR_COLOR)) - return - if pars[1] in relations: - del relations[pars[1]] + elif len(pars) > 2: + print(colorize("Too many parameter", ERROR_COLOR)) + if pars[1] in ui.relations: + ui.unload(pars[1]) completer.remove_completion(pars[1]) else: print(colorize("No such relation %s" % pars[1], ERROR_COLOR)) @@ -240,11 +240,8 @@ def exec_line(command: str) -> None: filename = pars[1] defname = pars[2] - if defname not in relations: - print(colorize("No such relation %s" % defname, ERROR_COLOR)) - return try: - relations[defname].save(filename) + ui.store(filename, defname) except Exception as e: print(colorize(e, ERROR_COLOR)) else: @@ -298,7 +295,7 @@ def exec_query(command: str) -> None: # Execute query try: pyquery = parser.parse(query) - result = pyquery(relations) + result = pyquery(ui.relations) printtty(colorize("-> query: %s" % pyquery, COLOR_GREEN)) @@ -306,7 +303,7 @@ def exec_query(command: str) -> None: print() print(result) - relations[relname] = result + ui.relations[relname] = result completer.add_completion(relname) except Exception as e: diff --git a/tests_dir/a_join_a.result b/tests_dir/a_join_a.result index 7081477..d99d273 100644 --- a/tests_dir/a_join_a.result +++ b/tests_dir/a_join_a.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/a_joinf_a.result b/tests_dir/a_joinf_a.result index 7081477..d99d273 100644 --- a/tests_dir/a_joinf_a.result +++ b/tests_dir/a_joinf_a.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/a_joinl_a.result b/tests_dir/a_joinl_a.result index 7081477..d99d273 100644 --- a/tests_dir/a_joinl_a.result +++ b/tests_dir/a_joinl_a.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/a_joinr_a.result b/tests_dir/a_joinr_a.result index 7081477..d99d273 100644 --- a/tests_dir/a_joinr_a.result +++ b/tests_dir/a_joinr_a.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/c_not_python.result b/tests_dir/c_not_python.result index 1899391..ac17b22 100644 --- a/tests_dir/c_not_python.result +++ b/tests_dir/c_not_python.result @@ -1,4 +1 @@ -name -eve -john -duncan +{"content": [["eve"], ["john"], ["duncan"]], "header": ["name"]} \ No newline at end of file diff --git a/tests_dir/c_programmers.result b/tests_dir/c_programmers.result index 34d340e..ffb1e0f 100644 --- a/tests_dir/c_programmers.result +++ b/tests_dir/c_programmers.result @@ -1,6 +1 @@ -id,name,chief,age,skill -2,john,1,30,C -7,alia,1,28,C -5,duncan,4,30,C -0,jack,0,22,C -4,eve,0,25,C +{"content": [[5, "duncan", 4, 30, "C"], [0, "jack", 0, 22, "C"], [4, "eve", 0, 25, "C"], [2, "john", 1, 30, "C"], [7, "alia", 1, 28, "C"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/dates.result b/tests_dir/dates.result index ae3bab8..0eb7080 100644 --- a/tests_dir/dates.result +++ b/tests_dir/dates.result @@ -1,6 +1 @@ -"date" -"2008-12-12" -"2007-08-12" -"1985-05-09" -"1988-4-21" -"1992-7-27" \ No newline at end of file +{"content": [[{"day": 12, "year": 2008, "month": 12}], [{"day": 9, "year": 1985, "month": 5}], [{"day": 21, "year": 1988, "month": 4}], [{"day": 27, "year": 1992, "month": 7}], [{"day": 12, "year": 2007, "month": 8}]], "header": ["date"]} \ No newline at end of file diff --git a/tests_dir/dates_sel.result b/tests_dir/dates_sel.result index e6ff89a..79308c1 100644 --- a/tests_dir/dates_sel.result +++ b/tests_dir/dates_sel.result @@ -1,3 +1 @@ -date -2008-12-12 -2007-08-12 +{"content": [[{"day": 12, "year": 2008, "month": 12}], [{"day": 12, "year": 2007, "month": 8}]], "header": ["date"]} \ No newline at end of file diff --git a/tests_dir/fixed_len_name.result b/tests_dir/fixed_len_name.result index dccd9b3..9577ecd 100644 --- a/tests_dir/fixed_len_name.result +++ b/tests_dir/fixed_len_name.result @@ -1,12 +1 @@ -id,name,chief,age,skill -2,john,1,30,C -7,alia,1,28,C -1,carl,0,20,C++ -2,john,1,30,PHP -7,alia,1,28,Python -3,dean,1,33,C++ -7,alia,1,28,PHP -0,jack,0,22,Python -1,carl,0,20,Python -0,jack,0,22,C -1,carl,0,20,System Admin +{"content": [[3, "dean", 1, 33, "C++"], [2, "john", 1, 30, "PHP"], [1, "carl", 0, 20, "C++"], [1, "carl", 0, 20, "Python"], [2, "john", 1, 30, "C"], [0, "jack", 0, 22, "Python"], [7, "alia", 1, 28, "Python"], [7, "alia", 1, 28, "PHP"], [1, "carl", 0, 20, "System Admin"], [0, "jack", 0, 22, "C"], [7, "alia", 1, 28, "C"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/full_join.result b/tests_dir/full_join.result index 79fb045..436320a 100644 --- a/tests_dir/full_join.result +++ b/tests_dir/full_join.result @@ -1,19 +1 @@ -id,skill,name,chief,age -4,C++,eve,0,25 -4,C,eve,0,25 -7,C,alia,1,28 -9,Java,---,---,--- -0,Python,jack,0,22 -5,C,duncan,4,30 -4,Perl,eve,0,25 -2,C,john,1,30 -1,Python,carl,0,20 -5,Perl,duncan,4,30 -6,---,paul,4,30 -2,PHP,john,1,30 -0,C,jack,0,22 -7,Python,alia,1,28 -1,System Admin,carl,0,20 -7,PHP,alia,1,28 -1,C++,carl,0,20 -3,C++,dean,1,33 +{"content": [[7, "C", "alia", 1, 28], [2, "PHP", "john", 1, 30], [4, "C++", "eve", 0, 25], [7, "Python", "alia", 1, 28], [6, null, "paul", 4, 30], [0, "Python", "jack", 0, 22], [2, "C", "john", 1, 30], [1, "Python", "carl", 0, 20], [1, "System Admin", "carl", 0, 20], [3, "C++", "dean", 1, 33], [5, "Perl", "duncan", 4, 30], [5, "C", "duncan", 4, 30], [7, "PHP", "alia", 1, 28], [1, "C++", "carl", 0, 20], [0, "C", "jack", 0, 22], [9, "Java", null, null, null], [4, "C", "eve", 0, 25], [4, "Perl", "eve", 0, 25]], "header": ["id", "skill", "name", "chief", "age"]} diff --git a/tests_dir/intersection1.result b/tests_dir/intersection1.result index 09dd8f0..a81c6b3 100644 --- a/tests_dir/intersection1.result +++ b/tests_dir/intersection1.result @@ -1,2 +1 @@ -id,name,chief,age -4,eve,0,25 +{"content": [[4, "eve", 0, 25]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/intersection2.result b/tests_dir/intersection2.result index 09dd8f0..a81c6b3 100644 --- a/tests_dir/intersection2.result +++ b/tests_dir/intersection2.result @@ -1,2 +1 @@ -id,name,chief,age -4,eve,0,25 +{"content": [[4, "eve", 0, 25]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/java_and_perl.result b/tests_dir/java_and_perl.result index 02755db..b7c8870 100644 --- a/tests_dir/java_and_perl.result +++ b/tests_dir/java_and_perl.result @@ -1,3 +1 @@ -name -duncan -eve +{"content": [["eve"], ["duncan"]], "header": ["name"]} \ No newline at end of file diff --git a/tests_dir/join.result b/tests_dir/join.result index 07cd4a7..e9f6d38 100644 --- a/tests_dir/join.result +++ b/tests_dir/join.result @@ -1,17 +1 @@ -id,name,chief,age,skill -2,john,1,30,C -7,alia,1,28,C -4,eve,0,25,C++ -4,eve,0,25,C -5,duncan,4,30,Perl -1,carl,0,20,C++ -7,alia,1,28,PHP -7,alia,1,28,Python -3,dean,1,33,C++ -1,carl,0,20,Python -2,john,1,30,PHP -0,jack,0,22,Python -0,jack,0,22,C -1,carl,0,20,System Admin -4,eve,0,25,Perl -5,duncan,4,30,C +{"content": [[2, "john", 1, 30, "PHP"], [5, "duncan", 4, 30, "Perl"], [2, "john", 1, 30, "C"], [4, "eve", 0, 25, "Perl"], [1, "carl", 0, 20, "System Admin"], [3, "dean", 1, 33, "C++"], [4, "eve", 0, 25, "C++"], [1, "carl", 0, 20, "C++"], [1, "carl", 0, 20, "Python"], [0, "jack", 0, 22, "Python"], [7, "alia", 1, 28, "Python"], [5, "duncan", 4, 30, "C"], [7, "alia", 1, 28, "PHP"], [4, "eve", 0, 25, "C"], [0, "jack", 0, 22, "C"], [7, "alia", 1, 28, "C"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/left_join.result b/tests_dir/left_join.result index 75b24c4..fc40eaa 100644 --- a/tests_dir/left_join.result +++ b/tests_dir/left_join.result @@ -1,18 +1 @@ -id,name,chief,age,skill -2,john,1,30,C -7,alia,1,28,C -4,eve,0,25,C++ -6,paul,4,30,--- -5,duncan,4,30,Perl -1,carl,0,20,C++ -7,alia,1,28,PHP -4,eve,0,25,C -7,alia,1,28,Python -3,dean,1,33,C++ -1,carl,0,20,Python -2,john,1,30,PHP -0,jack,0,22,Python -0,jack,0,22,C -1,carl,0,20,System Admin -4,eve,0,25,Perl -5,duncan,4,30,C +{"content": [[2, "john", 1, 30, "PHP"], [5, "duncan", 4, 30, "Perl"], [2, "john", 1, 30, "C"], [6, "paul", 4, 30, null], [4, "eve", 0, 25, "Perl"], [1, "carl", 0, 20, "System Admin"], [3, "dean", 1, 33, "C++"], [4, "eve", 0, 25, "C++"], [1, "carl", 0, 20, "C++"], [1, "carl", 0, 20, "Python"], [0, "jack", 0, 22, "Python"], [7, "alia", 1, 28, "Python"], [5, "duncan", 4, 30, "C"], [7, "alia", 1, 28, "PHP"], [4, "eve", 0, 25, "C"], [0, "jack", 0, 22, "C"], [7, "alia", 1, 28, "C"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/max_rating_in_age_range.result b/tests_dir/max_rating_in_age_range.result index 5d1f9f3..91eed6b 100644 --- a/tests_dir/max_rating_in_age_range.result +++ b/tests_dir/max_rating_in_age_range.result @@ -1,2 +1 @@ -id,name,chief,age,rating -1,carl,0,20,6 +{"content": [[1, "carl", 0, 20, 6]], "header": ["id", "name", "chief", "age", "rating"]} \ No newline at end of file diff --git a/tests_dir/maxdate.result b/tests_dir/maxdate.result index bde2e23..3a82e18 100644 --- a/tests_dir/maxdate.result +++ b/tests_dir/maxdate.result @@ -1,2 +1 @@ -date -2008-12-12 +{"content": [[{"day": 12, "year": 2008, "month": 12}]], "header": ["date"]} \ No newline at end of file diff --git a/tests_dir/name_age.result b/tests_dir/name_age.result index c9cc9bf..606e89a 100644 --- a/tests_dir/name_age.result +++ b/tests_dir/name_age.result @@ -1,9 +1 @@ -name,age -eve,25 -dean,33 -carl,20 -paul,30 -john,30 -jack,22 -duncan,30 -alia,28 +{"content": [["eve", 25], ["duncan", 30], ["paul", 30], ["carl", 20], ["alia", 28], ["dean", 33], ["jack", 22], ["john", 30]], "header": ["name", "age"]} \ No newline at end of file diff --git a/tests_dir/older_than_boss.result b/tests_dir/older_than_boss.result index 92af55b..555a259 100644 --- a/tests_dir/older_than_boss.result +++ b/tests_dir/older_than_boss.result @@ -1,7 +1 @@ -name,age,chief_name,chief_age -dean,33,carl,20 -alia,28,carl,20 -paul,30,eve,25 -eve,25,jack,22 -john,30,carl,20 -duncan,30,eve,25 +{"content": [["dean", 33, "carl", 20], ["duncan", 30, "eve", 25], ["john", 30, "carl", 20], ["alia", 28, "carl", 20], ["eve", 25, "jack", 22], ["paul", 30, "eve", 25]], "header": ["name", "age", "chief_name", "chief_age"]} \ No newline at end of file diff --git a/tests_dir/par1.result b/tests_dir/par1.result index 9d637aa..f2109d1 100644 --- a/tests_dir/par1.result +++ b/tests_dir/par1.result @@ -1 +1 @@ -id,name,chief,age +{"content": [], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/par2.result b/tests_dir/par2.result index 9d637aa..f2109d1 100644 --- a/tests_dir/par2.result +++ b/tests_dir/par2.result @@ -1 +1 @@ -id,name,chief,age +{"content": [], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/par3.result b/tests_dir/par3.result index 9d637aa..f2109d1 100644 --- a/tests_dir/par3.result +++ b/tests_dir/par3.result @@ -1 +1 @@ -id,name,chief,age +{"content": [], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/par4.result b/tests_dir/par4.result index 9d637aa..f2109d1 100644 --- a/tests_dir/par4.result +++ b/tests_dir/par4.result @@ -1 +1 @@ -id,name,chief,age +{"content": [], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/people.result b/tests_dir/people.result index 7081477..d99d273 100644 --- a/tests_dir/people.result +++ b/tests_dir/people.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/people_fjoin_personroom.result b/tests_dir/people_fjoin_personroom.result index 2501391..49c0aa9 100644 --- a/tests_dir/people_fjoin_personroom.result +++ b/tests_dir/people_fjoin_personroom.result @@ -1,9 +1 @@ -id,name,chief,age,room -0,jack,0,22,1 -1,carl,0,20,4 -2,john,1,30,2 -3,dean,1,33,2 -4,eve,0,25,5 -5,duncan,4,30,1 -6,paul,4,30,5 -7,alia,1,28,1 +{"content": [[5, "duncan", 4, 30, 1], [4, "eve", 0, 25, 5], [0, "jack", 0, 22, 1], [2, "john", 1, 30, 2], [1, "carl", 0, 20, 4], [6, "paul", 4, 30, 5], [7, "alia", 1, 28, 1], [3, "dean", 1, 33, 2]], "header": ["id", "name", "chief", "age", "room"]} \ No newline at end of file diff --git a/tests_dir/people_join_personroom.result b/tests_dir/people_join_personroom.result index 2501391..49c0aa9 100644 --- a/tests_dir/people_join_personroom.result +++ b/tests_dir/people_join_personroom.result @@ -1,9 +1 @@ -id,name,chief,age,room -0,jack,0,22,1 -1,carl,0,20,4 -2,john,1,30,2 -3,dean,1,33,2 -4,eve,0,25,5 -5,duncan,4,30,1 -6,paul,4,30,5 -7,alia,1,28,1 +{"content": [[5, "duncan", 4, 30, 1], [4, "eve", 0, 25, 5], [0, "jack", 0, 22, 1], [2, "john", 1, 30, 2], [1, "carl", 0, 20, 4], [6, "paul", 4, 30, 5], [7, "alia", 1, 28, 1], [3, "dean", 1, 33, 2]], "header": ["id", "name", "chief", "age", "room"]} \ No newline at end of file diff --git a/tests_dir/people_join_rooms.result b/tests_dir/people_join_rooms.result index 108efc3..1e59835 100644 --- a/tests_dir/people_join_rooms.result +++ b/tests_dir/people_join_rooms.result @@ -1,13 +1 @@ -id,name,chief,age,room,phone -0,jack,0,22,1,1516 -1,carl,0,20,4,1041 -2,john,1,30,2,1617 -3,dean,1,33,2,1617 -4,eve,0,25,5,9212 -5,duncan,4,30,1,1516 -6,paul,4,30,5,9212 -7,alia,1,28,1,1516 ----,---,---,---,"0","1515" ----,---,---,---,"3","1601" ----,---,---,---,"6","1424" ----,---,---,---,"7","1294" +{"content": [[0, "jack", 0, 22, 1, 1516], [null, null, null, null, 6, 1424], [null, null, null, null, 3, 1601], [7, "alia", 1, 28, 1, 1516], [2, "john", 1, 30, 2, 1617], [3, "dean", 1, 33, 2, 1617], [5, "duncan", 4, 30, 1, 1516], [4, "eve", 0, 25, 5, 9212], [1, "carl", 0, 20, 4, 1041], [null, null, null, null, 0, 1515], [null, null, null, null, 7, 1294], [6, "paul", 4, 30, 5, 9212]], "header": ["id", "name", "chief", "age", "room", "phone"]} diff --git a/tests_dir/people_join_select_args_on_both_tables.result b/tests_dir/people_join_select_args_on_both_tables.result index 57c4154..5e5d414 100644 --- a/tests_dir/people_join_select_args_on_both_tables.result +++ b/tests_dir/people_join_select_args_on_both_tables.result @@ -1,2 +1 @@ -id,name,chief,age,skill -0,jack,0,22,C +{"content": [[0, "jack", 0, 22, "C"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/people_rename.result b/tests_dir/people_rename.result index 6e4a1ba..5b734ec 100644 --- a/tests_dir/people_rename.result +++ b/tests_dir/people_rename.result @@ -1,9 +1 @@ -id,n,chief,a -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "n", "chief", "a"]} \ No newline at end of file diff --git a/tests_dir/people_rename_select.result b/tests_dir/people_rename_select.result index 83a690c..00e30c9 100644 --- a/tests_dir/people_rename_select.result +++ b/tests_dir/people_rename_select.result @@ -1,5 +1 @@ -i,name,chief,age -0,jack,0,22 -2,john,1,30 -4,eve,0,25 -6,paul,4,30 +{"content": [[4, "eve", 0, 25], [6, "paul", 4, 30], [2, "john", 1, 30], [0, "jack", 0, 22]], "header": ["i", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/phones_of_people_with_personal_room.result b/tests_dir/phones_of_people_with_personal_room.result index ebd829a..d6d6901 100644 --- a/tests_dir/phones_of_people_with_personal_room.result +++ b/tests_dir/phones_of_people_with_personal_room.result @@ -1,2 +1 @@ -phone,name -1041,carl +{"content": [[1041, "carl"]], "header": ["phone", "name"]} \ No newline at end of file diff --git a/tests_dir/php.result b/tests_dir/php.result index 15b2bff..b6d5f4d 100644 --- a/tests_dir/php.result +++ b/tests_dir/php.result @@ -1,2 +1 @@ -id,name,chief,age,skill -7,alia,1,28,PHP +{"content": [[7, "alia", 1, 28, "PHP"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/python_and_c.result b/tests_dir/python_and_c.result index 6eb3d0c..ad43f00 100644 --- a/tests_dir/python_and_c.result +++ b/tests_dir/python_and_c.result @@ -1,3 +1 @@ -name -jack -alia +{"content": [["alia"], ["jack"]], "header": ["name"]} \ No newline at end of file diff --git a/tests_dir/quot1.result b/tests_dir/quot1.result index 9d637aa..f2109d1 100644 --- a/tests_dir/quot1.result +++ b/tests_dir/quot1.result @@ -1 +1 @@ -id,name,chief,age +{"content": [], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/redoundant_union_select.result b/tests_dir/redoundant_union_select.result index 9408a8d..a575600 100644 --- a/tests_dir/redoundant_union_select.result +++ b/tests_dir/redoundant_union_select.result @@ -1,2 +1 @@ -id,name,chief,age -2,john,1,30 +{"content": [[2, "john", 1, 30]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/right_join.result b/tests_dir/right_join.result index e8ef0bd..19cbcd1 100644 --- a/tests_dir/right_join.result +++ b/tests_dir/right_join.result @@ -1,18 +1 @@ -id,skill,name,chief,age -4,C++,eve,0,25 -2,C,john,1,30 -1,Python,carl,0,20 -4,C,eve,0,25 -1,C++,carl,0,20 -7,C,alia,1,28 -9,Java,---,---,--- -2,PHP,john,1,30 -0,Python,jack,0,22 -4,Perl,eve,0,25 -5,C,duncan,4,30 -7,Python,alia,1,28 -1,System Admin,carl,0,20 -5,Perl,duncan,4,30 -7,PHP,alia,1,28 -0,C,jack,0,22 -3,C++,dean,1,33 +{"content": [[7, "C", "alia", 1, 28], [2, "PHP", "john", 1, 30], [4, "C++", "eve", 0, 25], [7, "Python", "alia", 1, 28], [0, "Python", "jack", 0, 22], [2, "C", "john", 1, 30], [1, "Python", "carl", 0, 20], [1, "System Admin", "carl", 0, 20], [3, "C++", "dean", 1, 33], [5, "Perl", "duncan", 4, 30], [5, "C", "duncan", 4, 30], [7, "PHP", "alia", 1, 28], [1, "C++", "carl", 0, 20], [0, "C", "jack", 0, 22], [9, "Java", null, null, null], [4, "C", "eve", 0, 25], [4, "Perl", "eve", 0, 25]], "header": ["id", "skill", "name", "chief", "age"]} diff --git a/tests_dir/select_join.result b/tests_dir/select_join.result index 51a573d..ec573ee 100644 --- a/tests_dir/select_join.result +++ b/tests_dir/select_join.result @@ -1,2 +1 @@ -id,skill,name,chief,age -3,C++,dean,1,33 +{"content": [[3, "C++", "dean", 1, 33]], "header": ["id", "skill", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/select_join_opt.result b/tests_dir/select_join_opt.result index 8a76bff..8bc0c50 100644 --- a/tests_dir/select_join_opt.result +++ b/tests_dir/select_join_opt.result @@ -1,3 +1 @@ -id,name,chief,age,skill -0,jack,0,22,C -4,eve,0,25,C +{"content": [[4, "eve", 0, 25, "C"], [0, "jack", 0, 22, "C"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/select_people_join_rooms.query b/tests_dir/select_people_join_rooms.query index 2336072..3a22f62 100644 --- a/tests_dir/select_people_join_rooms.query +++ b/tests_dir/select_people_join_rooms.query @@ -1 +1 @@ -σid=='---' (people⧓person_room ⧓ rooms) +σ id is None (people⧓person_room ⧓ rooms) diff --git a/tests_dir/select_people_join_rooms.result b/tests_dir/select_people_join_rooms.result index 82eb158..64924d3 100644 --- a/tests_dir/select_people_join_rooms.result +++ b/tests_dir/select_people_join_rooms.result @@ -1,5 +1 @@ -id,name,chief,age,room,phone ----,---,---,---,"0","1515" ----,---,---,---,"3","1601" ----,---,---,---,"6","1424" ----,---,---,---,"7","1294" +{"content": [[null, null, null, null, 0, 1515], [null, null, null, null, 7, 1294], [null, null, null, null, 3, 1601], [null, null, null, null, 6, 1424]], "header": ["id", "name", "chief", "age", "room", "phone"]} \ No newline at end of file diff --git a/tests_dir/skill_of_best_person.result b/tests_dir/skill_of_best_person.result index 5d07f7d..a671f53 100644 --- a/tests_dir/skill_of_best_person.result +++ b/tests_dir/skill_of_best_person.result @@ -1,4 +1 @@ -name,age,skill -eve,25,Perl -eve,25,C -eve,25,C++ +{"content": [["eve", 25, "C++"], ["eve", 25, "C"], ["eve", 25, "Perl"]], "header": ["name", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/subtraction1.result b/tests_dir/subtraction1.result index 6dc5c97..bd1f905 100644 --- a/tests_dir/subtraction1.result +++ b/tests_dir/subtraction1.result @@ -1,8 +1 @@ -id,name,chief,age -3,dean,1,33 -6,paul,4,30 -2,john,1,30 -0,jack,0,22 -7,alia,1,28 -1,carl,0,20 -5,duncan,4,30 +{"content": [[3, "dean", 1, 33], [5, "duncan", 4, 30], [1, "carl", 0, 20], [0, "jack", 0, 22], [2, "john", 1, 30], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/subtraction2.result b/tests_dir/subtraction2.result index 9d637aa..f2109d1 100644 --- a/tests_dir/subtraction2.result +++ b/tests_dir/subtraction2.result @@ -1 +1 @@ -id,name,chief,age +{"content": [], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/swap_fields.result b/tests_dir/swap_fields.result index 7081477..d99d273 100644 --- a/tests_dir/swap_fields.result +++ b/tests_dir/swap_fields.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/union1.result b/tests_dir/union1.result index dea402b..4d5f28e 100644 --- a/tests_dir/union1.result +++ b/tests_dir/union1.result @@ -1,4 +1 @@ -id,name,chief,age -7,alia,1,28 -4,eve,0,25 -0,jack,0,22 +{"content": [[4, "eve", 0, 25], [0, "jack", 0, 22], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/union2.result b/tests_dir/union2.result index 0c5da4e..d99d273 100644 --- a/tests_dir/union2.result +++ b/tests_dir/union2.result @@ -1,9 +1 @@ -id,name,chief,age -3,dean,1,33 -6,paul,4,30 -2,john,1,30 -0,jack,0,22 -7,alia,1,28 -1,carl,0,20 -4,eve,0,25 -5,duncan,4,30 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/union3.result b/tests_dir/union3.result index 0c5da4e..d99d273 100644 --- a/tests_dir/union3.result +++ b/tests_dir/union3.result @@ -1,9 +1 @@ -id,name,chief,age -3,dean,1,33 -6,paul,4,30 -2,john,1,30 -0,jack,0,22 -7,alia,1,28 -1,carl,0,20 -4,eve,0,25 -5,duncan,4,30 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/union4.result b/tests_dir/union4.result index 7081477..d99d273 100644 --- a/tests_dir/union4.result +++ b/tests_dir/union4.result @@ -1,9 +1 @@ -id,name,chief,age -0,jack,0,22 -1,carl,0,20 -2,john,1,30 -3,dean,1,33 -4,eve,0,25 -5,duncan,4,30 -6,paul,4,30 -7,alia,1,28 +{"content": [[1, "carl", 0, 20], [2, "john", 1, 30], [3, "dean", 1, 33], [5, "duncan", 4, 30], [0, "jack", 0, 22], [4, "eve", 0, 25], [6, "paul", 4, 30], [7, "alia", 1, 28]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/union_and_select.result b/tests_dir/union_and_select.result index 98379d8..c79100e 100644 --- a/tests_dir/union_and_select.result +++ b/tests_dir/union_and_select.result @@ -1,4 +1 @@ -id,skill -0,C -2,C -4,C +{"content": [[2, "C"], [0, "C"], [4, "C"]], "header": ["id", "skill"]} \ No newline at end of file diff --git a/tests_dir/union_join.result b/tests_dir/union_join.result index df2f9b0..e28ef51 100644 --- a/tests_dir/union_join.result +++ b/tests_dir/union_join.result @@ -1,8 +1 @@ -id,name,chief,age,skill -4,eve,0,25,C -5,duncan,4,30,C -2,john,1,30,C -7,alia,1,28,C -4,eve,0,25,Perl -5,duncan,4,30,Perl -0,jack,0,22,C +{"content": [[4, "eve", 0, 25, "C"], [5, "duncan", 4, 30, "C"], [0, "jack", 0, 22, "C"], [5, "duncan", 4, 30, "Perl"], [2, "john", 1, 30, "C"], [7, "alia", 1, 28, "C"], [4, "eve", 0, 25, "Perl"]], "header": ["id", "name", "chief", "age", "skill"]} \ No newline at end of file diff --git a/tests_dir/union_not_select.result b/tests_dir/union_not_select.result index b92ce90..a2aff9a 100644 --- a/tests_dir/union_not_select.result +++ b/tests_dir/union_not_select.result @@ -1,3 +1 @@ -id,skill -5,C -7,C +{"content": [[7, "C"], [5, "C"]], "header": ["id", "skill"]} \ No newline at end of file diff --git a/tests_dir/union_or_select.result b/tests_dir/union_or_select.result index 5386f2f..35201cb 100644 --- a/tests_dir/union_or_select.result +++ b/tests_dir/union_or_select.result @@ -1,3 +1 @@ -id,name,chief,age -3,dean,1,33 -1,carl,0,20 +{"content": [[3, "dean", 1, 33], [1, "carl", 0, 20]], "header": ["id", "name", "chief", "age"]} \ No newline at end of file diff --git a/tests_dir/union_projection.result b/tests_dir/union_projection.result index 7e0ab5d..1a1d483 100644 --- a/tests_dir/union_projection.result +++ b/tests_dir/union_projection.result @@ -1,8 +1 @@ -name,skill -jack,C -eve,Perl -duncan,Perl -duncan,C -john,C -alia,C -eve,C +{"content": [["jack", "C"], ["eve", "C"], ["duncan", "C"], ["alia", "C"], ["eve", "Perl"], ["duncan", "Perl"], ["john", "C"]], "header": ["name", "skill"]} \ No newline at end of file diff --git a/tests_dir/younger.result b/tests_dir/younger.result index f41e0cf..6527b54 100644 --- a/tests_dir/younger.result +++ b/tests_dir/younger.result @@ -1,2 +1 @@ -id,age,chief,name -1,20,0,carl +{"content": [[1, 20, 0, "carl"]], "header": ["id", "age", "chief", "name"]} \ No newline at end of file