예제 #1
0
def main():
    db.load_contents()
    db.print_contents()
    cont = True
    while cont:
        query = raw_input("hdsql>> ")
        try:
            if query.upper() == "QUIT":
                print "Bye"
                cont = False
            else:
                for command in sqlparse.split(query):
                    stmt = sqlparse.parse(
                        sqlparse.format(command, keyword_case='upper'))
                    stmt = stmt[0].tokens
                    qtype = str(stmt[0])
                    if len(stmt) < 7:
                        raise SqlException("Invalid Syntax")
                    if qtype == "SELECT":
                        try:
                            select_query(stmt)
                        except SqlException, e:
                            print e.message
                        except:
                            raise SqlException(
                                "Syntax Error/Query Execution Error")
예제 #2
0
    def get_col(self, col_name):
        """
				returns the column col of the table
			"""
        if "(" in col_name:  # some aggregate function exists
            aggregate = col_name.split("(")[0].upper()
            key = col_name.split("(")[1].split(")")[0]
        else:
            key = col_name
            aggregate = None

        # for queries where columns are specified without <table_name>.<column_name> format
        if "." not in key:
            key = check_overlapping_fields(self.columns, key)

        if key not in self.columns:
            raise SqlException("No such column: " + key)

        column = [row[key] for row in self.rows]
        if len(column) is 0:
            return [None]
        if aggregate is not None:
            if aggregate == "MAX":
                return [max(column)]
            elif aggregate == "MIN":
                return [min(column)]
            elif aggregate == "AVG":
                return [float(sum(column)) / len(column)]
            elif aggregate == "SUM":
                return [sum(column)]
            elif aggregate == "DISTINCT":
                return list(set(column))
            else:
                raise SqlException("Unknown aggregate function")
        return column
예제 #3
0
def where_helper(temp_table, all_columns, where):
    """
		Helper function for where; returns only first comparison results,
		thereby helping in only where and AND conditions
	"""
    try:
        comparison = where.tokens[2]  # comparison = "A=8";
        comparison.tokens = [
            x for x in comparison.tokens if not x.is_whitespace()
        ]  # No more white spaces
        key = str(comparison.tokens[0])  # key = "A"

        if '.' not in key:
            key = check_overlapping_fields(all_columns, key)
        try:
            value = int(
                str(comparison.tokens[2])
            )  # whether it is an integer value on RHS of comparison or some column
            temp_table.delete_rows_by_int(key, value,
                                          str(comparison.tokens[1]))
        except:
            value = str(comparison.tokens[2])
            if '.' not in value:
                value = check_overlapping_fields(all_columns, value)
            temp_table.delete_rows_by_col(key, value,
                                          str(comparison.tokens[1]))
    except:
        raise SqlException("Invalid Syntax")
    return temp_table
예제 #4
0
    def get_table(self, name):
        """
			returns the table with name name from this database
		"""
        t = filter(lambda x: x.name == name, self.tables)
        if len(t) == 0:
            raise SqlException("No such table")
        return t[0]
예제 #5
0
def check_overlapping_fields(columns, key):
    fl = False
    old_key = key
    for col in columns:
        if col.split(".")[1] == old_key:
            if fl:
                raise SqlException(
                    "EC: Joined tables have one of the fields overlapping. So, you need to specify in <table_name>.<column_name> format"
                )
            key = col
            fl = True
    return key
예제 #6
0
    def __make_row(self, row):
        """
				returns a row in dict form
			"""
        values = row.split(",")
        values = map(lambda x: int(x), values)

        if len(values) != len(self.columns):
            raise SqlException(
                "One of the rows is not of appropriate length in table " +
                self.name)

        return dict(zip(self.columns, values))
예제 #7
0
    def delete_rows_by_col(self, key, value, condition):
        """
				delete rows where column 'key' has value 'value' and the condition doesn't hold
			"""
        try:
            if condition.strip() == "!=" or condition.strip() == "<>":
                self.rows = filter(lambda x: x[key] != x[value], self.rows)
            elif condition.strip() == "=":
                self.rows = filter(lambda x: x[key] == x[value], self.rows)
            elif condition.strip() == ">=":
                self.rows = filter(lambda x: x[key] >= x[value], self.rows)
            elif condition.strip() == "<=":
                self.rows = filter(lambda x: x[key] <= x[value], self.rows)
            elif condition.strip() == ">":
                self.rows = filter(lambda x: x[key] > x[value], self.rows)
            elif condition.strip() == "<":
                self.rows = filter(lambda x: x[key] < x[value], self.rows)
        except:
            raise SqlException("Invalid column name")
예제 #8
0
    def delete_rows_by_both_cols(self, key1, value1, condition1, key2, value2,
                                 condition2):
        """
				delete rows where column 'key' has value 'value' and the condition doesn't hold
			"""
        try:
            if condition1.strip() == "!=" or condition1.strip() == "<>":
                if condition2.strip() == "!=" or condition2.strip() == "<>":
                    self.rows = filter(
                        lambda x: x[key1] != x[value1] or x[key2] != x[value2],
                        self.rows)
                elif condition2.strip() == "=":
                    self.rows = filter(
                        lambda x: x[key1] != x[value1] or x[key2] == x[value2],
                        self.rows)
                elif condition2.strip() == ">=":
                    self.rows = filter(
                        lambda x: x[key1] != x[value1] or x[key2] >= x[value2],
                        self.rows)
                elif condition2.strip() == "<=":
                    self.rows = filter(
                        lambda x: x[key1] != x[value1] or x[key2] <= x[value2],
                        self.rows)
                elif condition2.strip() == ">":
                    self.rows = filter(
                        lambda x: x[key1] != x[value1] or x[key2] > x[value2],
                        self.rows)
                elif condition2.strip() == "<":
                    self.rows = filter(
                        lambda x: x[key1] != x[value1] or x[key2] < x[value2],
                        self.rows)
            elif condition1.strip() == "=":
                if condition2.strip() == "!=" or condition2.strip() == "<>":
                    self.rows = filter(
                        lambda x: x[key1] == x[value1] or x[key2] != x[value2],
                        self.rows)
                elif condition2.strip() == "=":
                    self.rows = filter(
                        lambda x: x[key1] == x[value1] or x[key2] == x[value2],
                        self.rows)
                elif condition2.strip() == ">=":
                    self.rows = filter(
                        lambda x: x[key1] == x[value1] or x[key2] >= x[value2],
                        self.rows)
                elif condition2.strip() == "<=":
                    self.rows = filter(
                        lambda x: x[key1] == x[value1] or x[key2] <= x[value2],
                        self.rows)
                elif condition2.strip() == ">":
                    self.rows = filter(
                        lambda x: x[key1] == x[value1] or x[key2] > x[value2],
                        self.rows)
                elif condition2.strip() == "<":
                    self.rows = filter(
                        lambda x: x[key1] == x[value1] or x[key2] < x[value2],
                        self.rows)
            elif condition1.strip() == ">=":
                if condition2.strip() == "!=" or condition2.strip() == "<>":
                    self.rows = filter(
                        lambda x: x[key1] >= x[value1] or x[key2] != x[value2],
                        self.rows)
                elif condition2.strip() == "=":
                    self.rows = filter(
                        lambda x: x[key1] >= x[value1] or x[key2] == x[value2],
                        self.rows)
                elif condition2.strip() == ">=":
                    self.rows = filter(
                        lambda x: x[key1] >= x[value1] or x[key2] >= x[value2],
                        self.rows)
                elif condition2.strip() == "<=":
                    self.rows = filter(
                        lambda x: x[key1] >= x[value1] or x[key2] <= x[value2],
                        self.rows)
                elif condition2.strip() == ">":
                    self.rows = filter(
                        lambda x: x[key1] >= x[value1] or x[key2] > x[value2],
                        self.rows)
                elif condition2.strip() == "<":
                    self.rows = filter(
                        lambda x: x[key1] >= x[value1] or x[key2] < x[value2],
                        self.rows)
            elif condition1.strip() == "<=":
                if condition2.strip() == "!=" or condition2.strip() == "<>":
                    self.rows = filter(
                        lambda x: x[key1] <= x[value1] or x[key2] != x[value2],
                        self.rows)
                elif condition2.strip() == "=":
                    self.rows = filter(
                        lambda x: x[key1] <= x[value1] or x[key2] == x[value2],
                        self.rows)
                elif condition2.strip() == ">=":
                    self.rows = filter(
                        lambda x: x[key1] <= x[value1] or x[key2] >= x[value2],
                        self.rows)
                elif condition2.strip() == "<=":
                    self.rows = filter(
                        lambda x: x[key1] <= x[value1] or x[key2] <= x[value2],
                        self.rows)
                elif condition2.strip() == ">":
                    self.rows = filter(
                        lambda x: x[key1] <= x[value1] or x[key2] > x[value2],
                        self.rows)
                elif condition2.strip() == "<":
                    self.rows = filter(
                        lambda x: x[key1] <= x[value1] or x[key2] < x[value2],
                        self.rows)
            elif condition1.strip() == ">":
                if condition2.strip() == "!=" or condition2.strip() == "<>":
                    self.rows = filter(
                        lambda x: x[key1] > x[value1] or x[key2] != x[value2],
                        self.rows)
                elif condition2.strip() == "=":
                    self.rows = filter(
                        lambda x: x[key1] > x[value1] or x[key2] == x[value2],
                        self.rows)
                elif condition2.strip() == ">=":
                    self.rows = filter(
                        lambda x: x[key1] > x[value1] or x[key2] >= x[value2],
                        self.rows)
                elif condition2.strip() == "<=":
                    self.rows = filter(
                        lambda x: x[key1] > x[value1] or x[key2] <= x[value2],
                        self.rows)
                elif condition2.strip() == ">":
                    self.rows = filter(
                        lambda x: x[key1] > x[value1] or x[key2] > x[value2],
                        self.rows)
                elif condition2.strip() == "<":
                    self.rows = filter(
                        lambda x: x[key1] > x[value1] or x[key2] < x[value2],
                        self.rows)
            elif condition1.strip() == "<":
                if condition2.strip() == "!=" or condition2.strip() == "<>":
                    self.rows = filter(
                        lambda x: x[key1] < x[value1] or x[key2] != x[value2],
                        self.rows)
                elif condition2.strip() == "=":
                    self.rows = filter(
                        lambda x: x[key1] < x[value1] or x[key2] == x[value2],
                        self.rows)
                elif condition2.strip() == ">=":
                    self.rows = filter(
                        lambda x: x[key1] < x[value1] or x[key2] >= x[value2],
                        self.rows)
                elif condition2.strip() == "<=":
                    self.rows = filter(
                        lambda x: x[key1] < x[value1] or x[key2] <= x[value2],
                        self.rows)
                elif condition2.strip() == ">":
                    self.rows = filter(
                        lambda x: x[key1] < x[value1] or x[key2] > x[value2],
                        self.rows)
                elif condition2.strip() == "<":
                    self.rows = filter(
                        lambda x: x[key1] < x[value1] or x[key2] < x[value2],
                        self.rows)
        except:
            raise SqlException("Invalid column name")
예제 #9
0
def where_select_query(temp_table, all_columns, where):
    """
		filter where condition on the basis of AND, OR or none
	"""
    if len(where.tokens) >= 7:  # AND or OR are present
        if str(where.tokens[4]) == "AND":
            temp_table = where_helper(temp_table, all_columns, where)

            comparison = where.tokens[6]  # comparison = "A=8";
            comparison.tokens = [
                x for x in comparison.tokens if not x.is_whitespace()
            ]  # No more white spaces
            key = str(comparison.tokens[0])  # key = "A"

            if '.' not in key:
                key = check_overlapping_fields(all_columns, key)
            try:
                value = int(
                    str(comparison.tokens[2])
                )  # whether it is an int value on RHS of comparison or some column
                temp_table.delete_rows_by_int(key, value,
                                              str(comparison.tokens[1]))
            except:
                value = str(comparison.tokens[2])
                if '.' not in value:
                    value = check_overlapping_fields(all_columns, value)
                temp_table.delete_rows_by_col(key, value,
                                              str(comparison.tokens[1]))

        elif str(where.tokens[4]) == "OR":

            comparison1 = where.tokens[2]  # comparison = "A=8";
            comparison1.tokens = [
                x for x in comparison1.tokens if not x.is_whitespace()
            ]  # No more white spaces
            key1 = str(comparison1.tokens[0])  # key = "A"

            if '.' not in key1:
                key1 = check_overlapping_fields(all_columns, key1)
            try:
                value1 = int(str(comparison1.tokens[2]))
            except:
                value1 = str(comparison1.tokens[2])
                if '.' not in value1:
                    value1 = check_overlapping_fields(all_columns, value1)

            comparison2 = where.tokens[6]  # comparison = "A=8";
            comparison2.tokens = [
                x for x in comparison2.tokens if not x.is_whitespace()
            ]  # No more white spaces
            key2 = str(comparison2.tokens[0])  # key = "A"

            if '.' not in key2:
                key2 = check_overlapping_fields(all_columns, key2)
            try:
                value2 = int(str(comparison2.tokens[2]))
            except:
                value2 = str(comparison2.tokens[2])
                if '.' not in value2:
                    value2 = check_overlapping_fields(all_columns, value2)

            if type(value1) == int and type(value2) == int:
                temp_table.delete_rows_by_both_ints(key1, value1,
                                                    str(comparison1.tokens[1]),
                                                    key2, value2,
                                                    str(comparison2.tokens[1]))
            elif type(value1) == str and type(value2) == str:
                temp_table.delete_rows_by_both_cols(key1, value1,
                                                    str(comparison1.tokens[1]),
                                                    key2, value2,
                                                    str(comparison2.tokens[1]))
            else:
                raise SqlException(
                    "Only OR on joins with either comparisons with int or columns in both conditions supported."
                )
        else:
            raise SqlException("Invalid where condition")
    elif len(where.tokens) <= 5:  # Only where is present
        temp_table = where_helper(temp_table, all_columns, where)
    else:
        raise SqlException("Invalid where syntax")
    return temp_table
예제 #10
0
def select_query(stmt):
    """
		returns results of select query
		We'll make a temporary table, store the result and then print it
	"""
    try:
        column_list = str(stmt[2]).split(",")
        column_list = [x.strip() for x in column_list]
        table_list = str(stmt[6]).split(",")
        table_list = [x.strip() for x in table_list]
    except:
        raise SqlException("Invalid Syntax")
    else:
        if len(table_list) != len(set(table_list)):
            raise SqlException("Not Unique Tables")
        all_columns = map(
            lambda x: db.get_table(x).prefix_table_name_to_columns(),
            table_list)

        # upperbound columns of the new table
        all_columns = reduce(
            lambda x, y: x + y,
            all_columns)  # make all column lists in table_list as one

        # temporary table with all columns
        temp_table = classes.Table(name="temp", columns=all_columns, rows=[])

        all_tables_rows = map(lambda x: db.get_table(x).get_rows(), table_list)
        # cross product of all rows between tables
        rows = list(
            itertools.product(*all_tables_rows)
        )  # NOTE: product() takes the elements of a list, and not the list
        # So, here it will be all_tables_rows's elements
        for each in rows:  # each is a tuple of rows i.e. lists, therefore,
            each = reduce(
                lambda x, y: x + y, each
            )  # reduce simply concatenates all the rows to form one row
            #debug.debug(each)
            temp_table.add_row(each)  # of temporary table

        if len(stmt) >= 9:  # 'where' is present
            where = stmt[8]  # where = "WHERE A=8"
            if str(where.tokens[0]) == "WHERE":
                temp_table = where_select_query(temp_table, all_columns, where)
            else:
                raise SqlException("Invalid Syntax")

        if '*' in column_list:
            temp_table.print_contents()
        else:
            temp = []
            for col in column_list:
                temp.append(temp_table.get_col(col))

            l = len(temp[0])
            for row in temp:
                if len(row) != l:
                    raise SqlException(
                        "Incompatible column lengths: Generally, this happens when there's an aggregated query wihtout GROUP BY having non-aggregated column"
                    )

            for col in column_list:
                print col + "\t",
            print

            for row in zip(*temp):
                for i in row:
                    print str(i) + "\t",
                print
예제 #11
0
    while cont:
        query = raw_input("hdsql>> ")
        try:
            if query.upper() == "QUIT":
                print "Bye"
                cont = False
            else:
                for command in sqlparse.split(query):
                    stmt = sqlparse.parse(
                        sqlparse.format(command, keyword_case='upper'))
                    stmt = stmt[0].tokens
                    qtype = str(stmt[0])
                    if len(stmt) < 7:
                        raise SqlException("Invalid Syntax")
                    if qtype == "SELECT":
                        try:
                            select_query(stmt)
                        except SqlException, e:
                            print e.message
                        except:
                            raise SqlException(
                                "Syntax Error/Query Execution Error")
                    else:
                        raise SqlException(qtype + " not supported.")
                    print
        except SqlException, e:
            print e.message


if __name__ == '__main__':
    main()