示例#1
0
    def __init__(self, case_when, from_clause, cte, cte_name, rename):
        #print(json.dumps(case_when, indent=2))
        self.case_when = case_when
        self.expr = None
        self.result = None

        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.rename = rename

        if "A_Expr" in self.case_when["expr"]:
            temp_case = self.case_when["expr"]["A_Expr"]
            left = temp_case["lexpr"]
            right = temp_case["rexpr"]
            operator = temp_case["name"][0]["String"]["str"]
            self.expr = AExpression(left, operator, right, self.from_clause,
                                    self.cte, self.cte_name, self.rename)

        if "A_Const" in self.case_when["result"]:
            temp_case = self.case_when["result"]["A_Const"]["val"]
            if "Integer" in temp_case:
                self.result = temp_case["Integer"]["ival"]
            elif "String" in temp_case:
                self.result = temp_case["String"]["str"]
            elif "Float" in temp_case:
                self.result = temp_case["Float"]["str"]
            elif "Null" in temp_case:
                self.result = "NULL"
        elif "ColumnRef" in self.case_when["result"]:
            col = Column(self.case_when["result"]["ColumnRef"],
                         self.from_clause, self.cte, self.cte_name,
                         self.rename)
            self.result = col.transform_into_cypher()
示例#2
0
class JoinCondition:
    def __init__(self, raw_join_cond, left, right):
        self.raw_join_cond = raw_join_cond
        self.location = None
        self.left_alias = left
        self.right_alias = right
        self.operator = None
        if "A_Expr" in self.raw_join_cond.keys():
            self.operator = self.raw_join_cond["A_Expr"]["name"][0]["String"][
                "str"]

        if "A_Expr" in self.raw_join_cond.keys():
            self.location = self.raw_join_cond["A_Expr"]["location"]
            if "ColumnRef" in self.raw_join_cond["A_Expr"]["lexpr"]:
                self.left = Column(
                    self.raw_join_cond["A_Expr"]["lexpr"]["ColumnRef"])

            if "ColumnRef" in self.raw_join_cond["A_Expr"]["rexpr"]:
                self.right = Column(
                    self.raw_join_cond["A_Expr"]["rexpr"]["ColumnRef"])

    def transform_into_cypher(self):
        res = ""
        res += self.left.transform_into_cypher() + " "
        res += self.operator + " "
        res += self.right.transform_into_cypher()
        return res
示例#3
0
    def __init__(self, raw_join_cond, left, right):
        self.raw_join_cond = raw_join_cond
        self.location = None
        self.left_alias = left
        self.right_alias = right
        self.operator = None
        if "A_Expr" in self.raw_join_cond.keys():
            self.operator = self.raw_join_cond["A_Expr"]["name"][0]["String"][
                "str"]

        if "A_Expr" in self.raw_join_cond.keys():
            self.location = self.raw_join_cond["A_Expr"]["location"]
            if "ColumnRef" in self.raw_join_cond["A_Expr"]["lexpr"]:
                self.left = Column(
                    self.raw_join_cond["A_Expr"]["lexpr"]["ColumnRef"])

            if "ColumnRef" in self.raw_join_cond["A_Expr"]["rexpr"]:
                self.right = Column(
                    self.raw_join_cond["A_Expr"]["rexpr"]["ColumnRef"])
示例#4
0
    def __init__(self, target_list, from_clause, cte=False, cte_name=""):
        self.res_target = target_list
        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.columns = []
        self.functions = []
        self.aexpressions = []

        for i, elem in enumerate(target_list):
            if "ResTarget" in elem:
                rename = None
                if "name" in elem["ResTarget"]:
                    rename = elem["ResTarget"]["name"]
                if "val" in elem["ResTarget"]:
                    temp_val = elem["ResTarget"]["val"]
                    if "ColumnRef" in temp_val:
                        col = Column(
                            temp_val["ColumnRef"], self.from_clause, self.cte, self.cte_name, rename)
                        self.columns.append(col)
                    elif "FuncCall" in temp_val:
                        func = FuncCall(
                            temp_val["FuncCall"], self.from_clause, self.cte, self.cte_name, rename, i)
                        col_refer = func.get_col_refer()
                        self.columns.append(col_refer)
                        self.functions.append(func)
                    elif "A_Expr" in temp_val:
                        left = temp_val["A_Expr"]["lexpr"]
                        right = temp_val["A_Expr"]["rexpr"]
                        operator = temp_val["A_Expr"]["name"][0]["String"]["str"]
                        a_expr = AExpression(
                            left, operator, right, self.from_clause, self.cte, self.cte_name, rename)
                        col_refer = a_expr.get_col_refer()
                        self.columns.append(col_refer)
                        self.aexpressions.append(a_expr)
                    elif "CaseExpr" in temp_val:
                        case_expr = CaseExpression(
                            temp_val["CaseExpr"], self.from_clause, self.cte, self.cte_name, rename)
                        self.columns.append(case_expr)
示例#5
0
    def __init__(self, left, operator, right, from_clause=None, cte=None, cte_name=None, rename=None):
        self.left_initial = left
        self.left = None
        self.operator = operator
        self.right_initial = right
        self.right = None
        self.col_refer = None
        self.expr = None

        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.rename = rename

        if "A_Const" in self.left_initial.keys():
            temp_left = self.left_initial["A_Const"]["val"]
            if "String" in temp_left:
                self.left = temp_left["String"]["str"]
            elif "Integer" in temp_left:
                self.left = temp_left["Integer"]["ival"]
            elif "Float" in temp_left:
                self.left = temp_left["Float"]["str"]
        elif "FuncCall" in self.left_initial.keys():
            self.left = FuncCall(
                self.left_initial["FuncCall"], self.from_clause, self.cte, self.cte_name, self.rename)
            self.col_refer = self.left.get_col_refer()
        elif "ColumnRef" in self.left_initial.keys():
            self.left = Column(
                self.left_initial["ColumnRef"], self.from_clause, True, self.cte_name, self.rename)

        if "A_Const" in self.right_initial.keys():
            temp_right = self.right_initial["A_Const"]["val"]
            if "String" in temp_right:
                self.right = temp_right["String"]["str"]
            elif "Integer" in temp_right:
                self.right = temp_right["Integer"]["ival"]
            elif "Float" in temp_right:
                self.right = temp_right["Float"]["str"]
        elif "FuncCall" in self.right_initial.keys():
            self.right = FuncCall(
                self.right_initial["FuncCall"], self.from_clause, self.cte, self.cte_name, self.rename)
            self.col_refer = self.right.get_col_refer()
        elif "ColumnRef" in self.right_initial.keys():
            self.right = Column(
                self.right_initial["ColumnRef"], self.from_clause, True, self.cte_name, self.rename)
示例#6
0
    def __init__(self, raw_expr, from_clause, cte=False, cte_name=""):
        self.raw_expr = raw_expr
        self.sources = []
        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.boolop = self.raw_expr["boolop"]
        self.mapped_boolop = None
        self.edge_types = graph_db.get_edge_types()

        self.joins = []
        self.possible_joins = []
        self.filters = []

        if self.boolop == 0:
            self.mapped_boolop = "AND"
        elif self.boolop == 1:
            self.mapped_boolop = "OR"
        elif self.boolop == 2:
            self.mapped_boolop = "NOT"

        # First possible join conditions are extracted from the boolean expression
        # Those joins that cannot be transformed into pattern match are appended to filter conditions

        for elem in self.raw_expr["args"]:
            if "A_Expr" in elem.keys():

                left_side = elem["A_Expr"]["lexpr"]
                right_side = elem["A_Expr"]["rexpr"]
                operator = elem["A_Expr"]["name"][0]["String"]["str"]

                if type(left_side) == dict and type(right_side) == dict:

                    if "ColumnRef" in left_side.keys(
                    ) and "ColumnRef" in right_side.keys():

                        left = Column(left_side["ColumnRef"], self.from_clause,
                                      self.cte, self.cte_name)
                        right = Column(right_side["ColumnRef"],
                                       self.from_clause, self.cte,
                                       self.cte_name)

                        left_table = left.get_collection()
                        right_table = right.get_collection()

                        if left_table and right_table:
                            if rel_db.contains_table(
                                    left_table) and rel_db.contains_table(
                                        right_table) and operator == "=":
                                fk = left.get_field()
                                pk = right.get_field()
                                """
                                It is not a trivial task to check if a collection of equalities given in the where clause defines a graph pattern.
                                This part relies on certain assumptions in the underlaying data transformation.
                                But nothing guarantees that the data transformation follows those assumptions and it does not need to follow them.
                                """

                                if fk + "_" + pk in self.edge_types:
                                    self.from_clause.add_join(left, right)
                                elif pk + "_" + fk in self.edge_types:
                                    self.from_clause.add_join(right, left)
                                else:
                                    self.filters.append(elem)
                            else:
                                self.filters.append(elem)
                        else:
                            self.filters.append(elem)
                    else:
                        self.filters.append(elem)
                else:
                    self.filters.append(elem)
            else:
                self.filters.append(elem)

        # Analyze those conditions that do not define graph patterns

        for elem in self.filters:
            if "BoolExpr" in elem.keys():
                self.sources.append(
                    BooleanExpression(elem["BoolExpr"], self.from_clause,
                                      self.cte, self.cte_name))
            elif "A_Expr" in elem.keys():
                self.sources.append(
                    Where(elem, self.from_clause, self.cte, self.cte_name))
            elif "NullTest" in elem.keys():
                self.sources.append(
                    Where(elem, self.from_clause, self.cte, self.cte_name))
示例#7
0
class AExpression:

    def __init__(self, left, operator, right, from_clause=None, cte=None, cte_name=None, rename=None):
        self.left_initial = left
        self.left = None
        self.operator = operator
        self.right_initial = right
        self.right = None
        self.col_refer = None
        self.expr = None

        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.rename = rename

        if "A_Const" in self.left_initial.keys():
            temp_left = self.left_initial["A_Const"]["val"]
            if "String" in temp_left:
                self.left = temp_left["String"]["str"]
            elif "Integer" in temp_left:
                self.left = temp_left["Integer"]["ival"]
            elif "Float" in temp_left:
                self.left = temp_left["Float"]["str"]
        elif "FuncCall" in self.left_initial.keys():
            self.left = FuncCall(
                self.left_initial["FuncCall"], self.from_clause, self.cte, self.cte_name, self.rename)
            self.col_refer = self.left.get_col_refer()
        elif "ColumnRef" in self.left_initial.keys():
            self.left = Column(
                self.left_initial["ColumnRef"], self.from_clause, True, self.cte_name, self.rename)

        if "A_Const" in self.right_initial.keys():
            temp_right = self.right_initial["A_Const"]["val"]
            if "String" in temp_right:
                self.right = temp_right["String"]["str"]
            elif "Integer" in temp_right:
                self.right = temp_right["Integer"]["ival"]
            elif "Float" in temp_right:
                self.right = temp_right["Float"]["str"]
        elif "FuncCall" in self.right_initial.keys():
            self.right = FuncCall(
                self.right_initial["FuncCall"], self.from_clause, self.cte, self.cte_name, self.rename)
            self.col_refer = self.right.get_col_refer()
        elif "ColumnRef" in self.right_initial.keys():
            self.right = Column(
                self.right_initial["ColumnRef"], self.from_clause, True, self.cte_name, self.rename)

    def transform_into_cypher(self, with_with=True):
        res = ""
        if with_with:
            res += "WITH *, "
        if self.left and self.right:
            if type(self.left) == str or type(self.left) == int:
                res += str(self.left) + " "
            else:
                res += self.left.transform_into_cypher(with_with=False) + " "

            res += self.operator + " "

            if type(self.right) == str or type(self.right) == int:
                res += str(self.right)
            else:
                res += self.right.transform_into_cypher(with_with=False)
            if with_with and self.col_refer:
                res += " AS " + self.col_refer.get_field()
        return res

    def get_col_refer(self):
        return self.col_refer
示例#8
0
    def __init__(self, func_call, from_clause, cte, cte_name, rename, index=0):
        self.func_call = func_call
        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.rename = rename
        self.col_refer = None
        self.func = None
        self.index = index
        self.distinct = False

        if "agg_distinct" in self.func_call:
            self.distinct = self.func_call["agg_distinct"]

        func_name = self.func_call["funcname"][-1]["String"]["str"]

        if func_name == "count":
            star = False
            if "agg_star" in self.func_call:
                star = self.func_call["agg_star"]
            if star:
                self.func = "count(*)"
                self.col_refer = Column(
                    {"fields": [{
                        "String": {
                            "str": "c" + str(self.index)
                        }
                    }]},
                    self.from_clause,
                    self.cte,
                    self.cte_name,
                    rename=self.rename,
                    accept_collection_alias=False)
            else:
                for elem in self.func_call["args"]:
                    if "CaseExpr" in elem:
                        from model_transformations.query_transformations.parse_tree_trasformations.case_expression import CaseExpression
                        case_expr = CaseExpression(elem["CaseExpr"],
                                                   self.from_clause, self.cte,
                                                   self.cte_name, self.rename)
                        if self.distinct:
                            self.func = "count(distinct " + \
                                case_expr.transform_into_cypher() + ")"
                        else:
                            self.func = "count( " + \
                                case_expr.transform_into_cypher() + ")"
                        self.col_refer = Column(
                            {
                                "fields": [{
                                    "String": {
                                        "str": "c" + str(self.index)
                                    }
                                }]
                            },
                            self.from_clause,
                            self.cte,
                            self.cte_name,
                            rename=self.rename,
                            accept_collection_alias=False)
                    elif "ColumnRef":
                        col = Column(elem["ColumnRef"], self.from_clause, True,
                                     self.cte_name, self.rename)
                        if self.distinct:
                            self.func = "count(distinct "
                        else:
                            self.func = "count("
                        self.func += col.transform_into_cypher(
                            with_with=False) + ")"
                        self.col_refer = Column(
                            {
                                "fields": [{
                                    "String": {
                                        "str": "c" + str(self.index)
                                    }
                                }]
                            },
                            self.from_clause,
                            self.cte,
                            self.cte_name,
                            rename=self.rename,
                            accept_collection_alias=False)

        else:
            call = pg_functions_to_neo4j_functions(self.func_call,
                                                   self.from_clause, self.cte,
                                                   self.cte_name, self.rename)
            for elem in call["fields"]:
                self.func = call["func"]["pre"] + elem.transform_into_cypher(
                    False) + call["func"]["post"]
            self.col_refer = Column(
                {"fields": [{
                    "String": {
                        "str": "func" + str(self.index)
                    }
                }]},
                self.from_clause,
                self.cte,
                self.cte_name,
                self.rename,
                accept_collection_alias=False)
示例#9
0
class Where:

    """
    This class implements only filtering conditional where clauses. Where clauses that create joins between tables are handled in Join class.

    In practice this means that this class handles all other cases expect those where parse tree has ColumnRef on both left and right side and these ColumnRefs induce a valid
    edge in the graph schema.

    /*
        * A_Expr - infix, prefix, and postfix expressions
    */
        typedef enum A_Expr_Kind
        {
            AEXPR_OP,                   /* 0 normal operator */
            AEXPR_OP_ANY,               /* 1 scalar op ANY (array) */
            AEXPR_OP_ALL,               /* 2 scalar op ALL (array) */
            AEXPR_DISTINCT,             /* 3 IS DISTINCT FROM - name must be "=" */
            AEXPR_NOT_DISTINCT,         /* 4 IS NOT DISTINCT FROM - name must be "=" */
            AEXPR_NULLIF,               /* 5 NULLIF - name must be "=" */
            AEXPR_IN,                   /* 6 [NOT] IN - name must be "=" or "<>" */
            AEXPR_LIKE,                 /* 7 [NOT] LIKE - name must be "~~" or "!~~" */
            AEXPR_ILIKE,                /* 8 [NOT] ILIKE - name must be "~~*" or "!~~*" */
            AEXPR_SIMILAR,              /* 9 [NOT] SIMILAR - name must be "~" or "!~" */
            AEXPR_BETWEEN,              /* 10 name must be "BETWEEN" */
            AEXPR_NOT_BETWEEN,          /* 11 name must be "NOT BETWEEN" */
            AEXPR_BETWEEN_SYM,          /* 12 name must be "BETWEEN SYMMETRIC" */
            AEXPR_NOT_BETWEEN_SYM       /* 13 name must be "NOT BETWEEN SYMMETRIC" */
        } A_Expr_Kind;

    """

    def __init__(self, where_clause, from_clause, cte=False, cte_name=""):
        #print(json.dumps(where_clause, indent = 2))
        self.where_clause = where_clause
        self.left = None
        self.operator = None
        self.right = None
        self.joins = []
        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.type = None
        self.left_side_typecasted = False
        self.right_side_typecasted = False
        self.kind = None

        if "A_Expr" in self.where_clause.keys():

            self.left_side = self.where_clause["A_Expr"]["lexpr"]
            self.right_side = self.where_clause["A_Expr"]["rexpr"]
            self.operator = self.where_clause["A_Expr"]["name"][0]["String"]["str"]
            self.kind = self.where_clause["A_Expr"]["kind"]

            if self.kind == 0:

                if type(self.left_side) == dict and type(self.right_side) == dict:

                    if "ColumnRef" in self.left_side.keys() and "ColumnRef" in self.right_side.keys():

                        self.left = Column(
                            self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                        self.right = Column(
                            self.right_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                    else:
                        if "ColumnRef" in self.left_side.keys():

                            self.left = Column(
                                self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                        elif "A_Const" in self.left_side.keys():

                            self.left = self.handle_a_const(self.left_side)

                        elif "TypeCast" in self.left_side.keys():
                            self.left, self.type = self.handle_typecast(
                                self.left_side)
                            self.left_side_typecasted = True

                        if "ColumnRef" in self.right_side.keys():

                            self.right = Column(
                                self.right_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                        elif "A_Const" in self.right_side.keys():
                            self.right = self.handle_a_const(self.right_side)

                        elif "TypeCast" in self.right_side.keys():
                            self.right, self.type = self.handle_typecast(
                                self.right_side)
                            self.right_side_typecasted = True

            elif self.kind == 7:

                if type(self.left_side) == dict and type(self.right_side) == list:

                    if "ColumnRef" in self.left_side.keys():
                        self.left = Column(
                            self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                    self.right = []
                    for elem in self.right_side:
                        if "A_Const" in elem.keys():
                            self.right.append(self.handle_a_const(elem))
                        elif "TypeCast" in elem.keys():
                            res, self.type = self.handle_typecast(
                                self.right_side)
                            self.right.append(res)
                            self.right_side_typecasted = True

            elif self.kind == 11:

                if type(self.left_side) == dict and type(self.right_side) == list:
                    if "ColumnRef" in self.left_side.keys():
                        self.left = Column(
                            self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                    self.right = []
                    for elem in self.right_side:
                        if "A_Const" in elem.keys():
                            self.right.append(self.handle_a_const(elem))
                        elif "TypeCast" in elem.keys():
                            res, self.type = self.handle_typecast(elem)
                            self.right.append(res)
                            self.right_side_typecasted = True

        elif "NullTest" in self.where_clause.keys():
            self.kind = "nulltest"
            self.left = Column(
                self.where_clause["NullTest"]["arg"]["ColumnRef"], self.from_clause, self.cte, self.cte_name)
            self.operator = "IS"
            self.right = "NULL"

    def transform_into_cypher(self, add_where=True):
        res = ""
        if self.left and self.right:
            if add_where:
                res = "WHERE "

            """
            Left side of the single where clause
            """

            if self.kind == 11:
                if self.operator == "BETWEEN":
                    if self.type == "timestamp":
                        if len(self.right) == 2:

                            """
                            Strange but Neo4j lacks datetime comparisions. Transforming datetimes into integers and comparing them is the workaround here.
                            """

                            res += self.right[0] + ".epochMillis " + " <= " + pg_types_to_neo4j_types(self.type,
                                                    self.left.transform_into_cypher(), "column") + ".epochMillis <= " + self.right[1] +".epochMillis" + "\n"
            else:

                if type(self.left) == str:
                    res += '"' + str(self.left) + '"'
                elif type(self.left) == int:
                    res += str(self.left)
                else:
                    if self.right_side_typecasted:
                        res += pg_types_to_neo4j_types(self.type,
                                                    self.left.transform_into_cypher(), "column") + " "
                    else:
                        res += self.left.transform_into_cypher() + " "

                """
                Operator i.e. equality, inequality or other comparision, inclusion etc.
                Most of the time Postgres and Neo4j have same naming here.
                """

                if self.kind == 7:
                    res += "IN "
                else:
                    res += self.operator + " "

                """
                Right side of the single where clause
                """

                if type(self.right) == str:
                    res += '"' + str(self.right) + '"'
                elif type(self.right) == int:
                    res += str(self.right)
                elif type(self.right) == list:
                    if self.kind == 7:
                        res += "["
                        for elem in self.right:
                            res += "'" + elem + "'" + ", "
                        res = res[0:-2] + "]"
                else:
                    if self.left_side_typecasted:
                        res += pg_types_to_neo4j_types(self.type,
                                                    self.right.transform_into_cypher(), "column") + " "
                    else:
                        res += self.right.transform_into_cypher()
                return res + "\n"

        return res + "\n"

    def get_left(self):
        return self.left

    def get_right(self):
        return self.right

    def handle_a_const(self, elem):
        temp = elem["A_Const"]["val"]
        if "Float" in temp.keys():
            return temp["Float"]["str"]
        elif "String" in temp.keys():
            return temp["String"]["str"]
        elif "Integer" in temp.keys():
            return temp["Integer"]["ival"]

    def handle_typecast(self, elem):
        value = elem["TypeCast"]["arg"]["A_Const"]["val"]["String"]["str"]
        type = elem["TypeCast"]["typeName"]["TypeName"]["names"][-1]["String"]["str"]
        result = pg_types_to_neo4j_types(type, value)
        return result, type
示例#10
0
    def __init__(self, where_clause, from_clause, cte=False, cte_name=""):
        #print(json.dumps(where_clause, indent = 2))
        self.where_clause = where_clause
        self.left = None
        self.operator = None
        self.right = None
        self.joins = []
        self.from_clause = from_clause
        self.cte = cte
        self.cte_name = cte_name
        self.type = None
        self.left_side_typecasted = False
        self.right_side_typecasted = False
        self.kind = None

        if "A_Expr" in self.where_clause.keys():

            self.left_side = self.where_clause["A_Expr"]["lexpr"]
            self.right_side = self.where_clause["A_Expr"]["rexpr"]
            self.operator = self.where_clause["A_Expr"]["name"][0]["String"]["str"]
            self.kind = self.where_clause["A_Expr"]["kind"]

            if self.kind == 0:

                if type(self.left_side) == dict and type(self.right_side) == dict:

                    if "ColumnRef" in self.left_side.keys() and "ColumnRef" in self.right_side.keys():

                        self.left = Column(
                            self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                        self.right = Column(
                            self.right_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                    else:
                        if "ColumnRef" in self.left_side.keys():

                            self.left = Column(
                                self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                        elif "A_Const" in self.left_side.keys():

                            self.left = self.handle_a_const(self.left_side)

                        elif "TypeCast" in self.left_side.keys():
                            self.left, self.type = self.handle_typecast(
                                self.left_side)
                            self.left_side_typecasted = True

                        if "ColumnRef" in self.right_side.keys():

                            self.right = Column(
                                self.right_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                        elif "A_Const" in self.right_side.keys():
                            self.right = self.handle_a_const(self.right_side)

                        elif "TypeCast" in self.right_side.keys():
                            self.right, self.type = self.handle_typecast(
                                self.right_side)
                            self.right_side_typecasted = True

            elif self.kind == 7:

                if type(self.left_side) == dict and type(self.right_side) == list:

                    if "ColumnRef" in self.left_side.keys():
                        self.left = Column(
                            self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                    self.right = []
                    for elem in self.right_side:
                        if "A_Const" in elem.keys():
                            self.right.append(self.handle_a_const(elem))
                        elif "TypeCast" in elem.keys():
                            res, self.type = self.handle_typecast(
                                self.right_side)
                            self.right.append(res)
                            self.right_side_typecasted = True

            elif self.kind == 11:

                if type(self.left_side) == dict and type(self.right_side) == list:
                    if "ColumnRef" in self.left_side.keys():
                        self.left = Column(
                            self.left_side["ColumnRef"], self.from_clause, self.cte, self.cte_name)

                    self.right = []
                    for elem in self.right_side:
                        if "A_Const" in elem.keys():
                            self.right.append(self.handle_a_const(elem))
                        elif "TypeCast" in elem.keys():
                            res, self.type = self.handle_typecast(elem)
                            self.right.append(res)
                            self.right_side_typecasted = True

        elif "NullTest" in self.where_clause.keys():
            self.kind = "nulltest"
            self.left = Column(
                self.where_clause["NullTest"]["arg"]["ColumnRef"], self.from_clause, self.cte, self.cte_name)
            self.operator = "IS"
            self.right = "NULL"