def distinct(table: Table, column):
    """ returns a filtered table where all rows are distinct """
    newTable = Table(table.name, table.schema)
    columnIndex = table.keyToPosDict[column]
    valueSet = set()
    for row in table:
        val = row[columnIndex]
        if val in valueSet:
            continue
        valueSet.add(val)
        newTable.append(row)

    return newTable
def where(table: Table, column, symbol, constant):
    """
    tuple = (column_name, operator, constant)
    SLECT * IS NOT NULL
    SELECT * WHERE id > 4;
     >, <,=, !=, IS NOT, IS.

      returns a filtered table
     """
    constant = None if constant == "NULL" else constant
    newTable = Table(table.name, table.schema)
    func = operatorDictionary[symbol]
    columnIndex = table.keyToPosDict[column]

    # for row in table: # suspicious
    #   row.cleanRow(table.schema) # suspicious

    for row in table:
        if row[columnIndex] is None and constant is not None:
            continue
        if func(row[columnIndex], constant):
            newTable.append(row)

    return newTable
예제 #3
0
    def leftOuterJoin(self, tokens):
        """
        "SELECT students.name, students.grade, classes.course, classes.instructor
        FROM students LEFT OUTER JOIN classes
        ON students.class = classes.course
        WHERE students.grade > 60
        ORDER BY classes.instructor, students.name, students.grade;"
        """

        whereArr = []
        if "WHERE" in tokens:
            tokens = list(tokens)
            whereIndex = tokens.index("WHERE")
            orderIndex = tokens.index("ORDER")
            whereArr = tokens[whereIndex:orderIndex]
            del tokens[whereIndex:orderIndex]
            tokens = deque(tokens)

        # PARSING STRING FIRST
        fields, leftTableName, rightTableName, leftJoinCol, rightJoinCol, orderByColumns = leftJoinParse(
            tokens)

        # Make deep copies of left and right tables
        leftTable: Table = deepcopy(self.db[leftTableName])
        rightTable: Table = deepcopy(self.db[rightTableName])

        newTableName = "joinedTable"
        newSchema = OrderedDict()

        for key, value in leftTable.schema.items():
            newKeyName = newTableName + "." + key
            newSchema[newKeyName] = value

        for key, value in rightTable.schema.items():
            newKeyName = newTableName + "." + key
            newSchema[newKeyName] = value

        newTable = Table(newTableName, newSchema)
        self.db[newTableName] = newTable

        lkeyToPosDict, rkeyToPosDict = leftTable.keyToPosDict, rightTable.keyToPosDict

        rightNones = len(rightTable[0]) * [None]

        # populate new table
        for lrow in leftTable:
            row = Row()

            if lrow.getVal(leftJoinCol, lkeyToPosDict) is None:
                row.extend(lrow + rightNones)
                newTable.append(row)
                continue
            for rrow in rightTable:
                if lrow.getVal(leftJoinCol, lkeyToPosDict) == rrow.getVal(
                        rightJoinCol, rkeyToPosDict):
                    row.extend(lrow + rrow)
                    newTable.append(row)  # needs fixing, maybe?
                    break  # there might be multiple tables with same matching id
            else:
                row.extend(lrow + rightNones)
                newTable.append(row)
                continue

        for i, field in enumerate(fields):
            fields[i] = addTableName(newTableName, field)

        for i, field in enumerate(orderByColumns):
            orderByColumns[i] = addTableName(newTableName, field)

        fieldsString = ", ".join(fields)
        orderString = ", ".join(orderByColumns)
        whereString = ""
        if whereArr:
            whereArr[1] = addTableName(newTableName, whereArr[1])
            whereArr = [str(i) for i in whereArr]  # maybe switch none to NULL
            whereString = " ".join(whereArr)

        query = " SELECT {} FROM {} {} ORDER BY {};".format(
            fieldsString, newTableName, whereString, orderString)

        result = self.executeHelper(query)

        # delete the table we created
        self.db.pop(newTableName)
        return result