예제 #1
0
파일: compile.py 프로젝트: sirex/htsql
 def clip_root(self, term, order):
     left_bound = 1
     if self.space.offset is not None:
         left_bound = self.space.offset+1
     right_bound = left_bound+1
     if self.space.limit is not None:
         right_bound = left_bound+self.space.limit
     term = OrderTerm(self.state.tag(), term, order, None, None,
                     term.space, term.baseline, term.routes.copy())
     term = PermanentTerm(self.state.tag(), term,
                          term.space, term.baseline, term.routes.copy())
     row_num_code = FormulaCode(RowNumSig(), coerce(IntegerDomain()),
                                self.space.flow)
     right_bound_code = LiteralCode(right_bound, coerce(IntegerDomain()),
                                    self.space.flow)
     right_filter = FormulaCode(CompareSig('<'), coerce(BooleanDomain()),
                                self.space.flow,
                                lop=row_num_code, rop=right_bound_code)
     term = FilterTerm(self.state.tag(), term, right_filter,
                       term.space, term.baseline, term.routes.copy())
     routes = term.routes.copy()
     row_num_unit = ScalarUnit(row_num_code, self.space, self.space.flow)
     routes[row_num_unit] = term.tag
     term = PermanentTerm(self.state.tag(), term,
                          term.space, term.baseline, routes)
     left_bound_code = LiteralCode(left_bound, coerce(IntegerDomain()),
                                   self.space.flow)
     left_filter = FormulaCode(CompareSig('>='), coerce(BooleanDomain()),
                               self.space.flow,
                               lop=row_num_unit, rop=left_bound_code)
     term = FilterTerm(self.state.tag(), term, left_filter,
                       term.space, term.baseline, term.routes.copy())
     return term
예제 #2
0
파일: compile.py 프로젝트: sirex/htsql
 def __call__(self):
     if self.space.limit is None and self.space.offset is None:
         return super(OracleCompileOrdered, self).__call__()
     left_limit = None
     if self.space.offset is not None:
         left_limit = self.space.offset+1
     right_limit = None
     if self.space.limit is not None:
         if self.space.offset is not None:
             right_limit = self.space.limit+self.space.offset+1
         else:
             right_limit = self.space.limit+1
     kid = self.state.compile(self.space.base,
                              baseline=self.state.root)
     order = arrange(self.space)
     kid = self.state.inject(kid, [code for code, direction in order])
     routes = kid.routes.copy()
     for unit in spread(self.space):
         routes[unit] = routes[unit.clone(space=self.backbone)]
     kid = OrderTerm(self.state.tag(), kid, order, None, None,
                     self.space, kid.baseline, routes)
     kid = PermanentTerm(self.state.tag(), kid,
                         kid.space, kid.baseline, kid.routes.copy())
     row_num_code = FormulaCode(RowNumSig(), coerce(IntegerDomain()),
                                self.space.flow)
     if right_limit is not None:
         right_limit_code = LiteralCode(right_limit,
                                        coerce(IntegerDomain()),
                                        self.space.flow)
         right_filter = FormulaCode(CompareSig('<'),
                                    coerce(BooleanDomain()),
                                    self.space.flow,
                                    lop=row_num_code,
                                    rop=right_limit_code)
         kid = FilterTerm(self.state.tag(), kid, right_filter,
                          kid.space, kid.baseline, kid.routes.copy())
     else:
         kid = WrapperTerm(self.state.tag(), kid,
                           kid.space, kid.baseline, kid.routes.copy())
     routes = kid.routes.copy()
     if left_limit is not None:
         row_num_unit = ScalarUnit(row_num_code, self.space.base,
                                   self.space.flow)
         routes[row_num_unit] = kid.tag
     kid = PermanentTerm(self.state.tag(), kid,
                         kid.space, kid.baseline, routes)
     if left_limit is not None:
         left_limit_code = LiteralCode(left_limit,
                                       coerce(IntegerDomain()),
                                       self.space.flow)
         left_filter = FormulaCode(CompareSig('>='),
                                   coerce(BooleanDomain()),
                                   self.space.flow,
                                   lop=row_num_unit,
                                   rop=left_limit_code)
         kid = FilterTerm(self.state.tag(), kid, left_filter,
                          kid.space, kid.baseline, kid.routes.copy())
     return kid
예제 #3
0
파일: compile.py 프로젝트: sirex/htsql
 def __call__(self):
     if self.space.offset is None:
         return super(MSSQLCompileOrdered, self).__call__()
     kid = self.state.compile(self.space.base,
                              baseline=self.state.root)
     order = arrange(self.space)
     kid = self.state.inject(kid, [code for code, direction in order])
     ops = []
     for code, direction in order:
         op = FormulaCode(SortDirectionSig(direction=direction),
                          code.domain, code.flow, base=code)
         ops.append(op)
     row_number_code = FormulaCode(RowNumberSig(), coerce(IntegerDomain()),
                                   self.space.flow,
                                   partition=[], order=ops)
     row_number_unit = ScalarUnit(row_number_code, self.space.base,
                                  self.space.flow)
     tag = self.state.tag()
     routes = kid.routes.copy()
     routes[row_number_unit] = tag
     kid = PermanentTerm(tag, kid, kid.space, kid.baseline, routes)
     left_limit = self.space.offset+1
     right_limit = None
     if self.space.limit is not None:
         right_limit = self.space.limit+self.space.offset+1
     left_limit_code = LiteralCode(left_limit, coerce(IntegerDomain()),
                                   self.space.flow)
     right_limit_code = None
     if right_limit is not None:
         right_limit_code = LiteralCode(right_limit, coerce(IntegerDomain()),
                                        self.space.flow)
     left_filter = FormulaCode(CompareSig('>='), coerce(BooleanDomain()),
                               self.space.flow,
                               lop=row_number_unit, rop=left_limit_code)
     right_filter = None
     if right_limit_code is not None:
         right_filter = FormulaCode(CompareSig('<'),
                                    coerce(BooleanDomain()),
                                    self.space.flow,
                                    lop=row_number_unit,
                                    rop=right_limit_code)
     filter = left_filter
     if right_filter is not None:
         filter = FormulaCode(AndSig(), coerce(BooleanDomain()),
                              self.space.flow,
                              ops=[left_filter, right_filter])
     routes = kid.routes.copy()
     for unit in spread(self.space):
         routes[unit] = routes[unit.clone(space=self.backbone)]
     return FilterTerm(self.state.tag(), kid, filter,
                       self.space, kid.baseline, routes)
예제 #4
0
 def __call__(self):
     lop = self.state.encode(self.flow.lop)
     rop = self.state.encode(self.flow.rop)
     if isinstance(rop, LiteralCode):
         if rop.value is not None:
             value = (u"%" + rop.value.replace(u"\\", u"\\\\")
                                      .replace(u"[", u"\\[")
                                      .replace(u"]", u"\\]")
                                      .replace(u"%", u"\\%")
                                      .replace(u"_", u"\\_") + u"%")
             rop = rop.clone(value=value)
     else:
         backslash_literal = LiteralCode(u"\\", rop.domain, self.flow)
         xbackslash_literal = LiteralCode(u"\\\\", rop.domain, self.flow)
         lbracket_literal = LiteralCode(u"[", rop.domain, self.flow)
         xlbracket_literal = LiteralCode(u"\\[", rop.domain, self.flow)
         rbracket_literal = LiteralCode(u"]", rop.domain, self.flow)
         xrbracket_literal = LiteralCode(u"\\]", rop.domain, self.flow)
         percent_literal = LiteralCode(u"%", rop.domain, self.flow)
         xpercent_literal = LiteralCode(u"\\%", rop.domain, self.flow)
         underscore_literal = LiteralCode(u"_", rop.domain, self.flow)
         xunderscore_literal = LiteralCode(u"\\_", rop.domain, self.flow)
         rop = FormulaCode(ReplaceSig(), rop.domain, self.flow,
                           op=rop, old=backslash_literal,
                           new=xbackslash_literal)
         rop = FormulaCode(ReplaceSig(), rop.domain, self.flow,
                           op=rop, old=lbracket_literal,
                           new=xlbracket_literal)
         rop = FormulaCode(ReplaceSig(), rop.domain, self.flow,
                           op=rop, old=rbracket_literal,
                           new=xrbracket_literal)
         rop = FormulaCode(ReplaceSig(), rop.domain, self.flow,
                           op=rop, old=percent_literal,
                           new=xpercent_literal)
         rop = FormulaCode(ReplaceSig(), rop.domain, self.flow,
                           op=rop, old=underscore_literal,
                           new=xunderscore_literal)
         rop = FormulaCode(ConcatenateSig(), rop.domain, self.flow,
                           lop=percent_literal, rop=rop)
         rop = FormulaCode(ConcatenateSig(), rop.domain, self.flow,
                           lop=rop, rop=percent_literal)
     return FormulaCode(self.signature.clone_to(LikeSig),
                        self.domain, self.flow, lop=lop, rop=rop)
예제 #5
0
 def clip(self, term, order, partition):
     prefix = "!htsql:%s" % term.tag
     row_number = FormulaCode(UserVariableSig("%s:row_number" % prefix),
                              coerce(IntegerDomain()), self.space.flow)
     keys = []
     for idx, code in enumerate(partition):
         key = FormulaCode(
             UserVariableSig("%s:partition:%s" % (prefix, idx + 1)),
             code.domain, self.space.flow)
         keys.append(key)
     #term = PermanentTerm(self.state.tag(), term,
     #                     term.space, term.baseline, term.routes.copy())
     zero_term = ScalarTerm(self.state.tag(), self.state.root,
                            self.state.root, {})
     zero_units = []
     code = FormulaCode(UserVariableAssignmentSig(),
                        row_number.domain,
                        self.space.flow,
                        lop=row_number,
                        rop=LiteralCode(None, row_number.domain,
                                        self.space.flow))
     unit = ScalarUnit(code, self.state.root, code.flow)
     zero_units.append(unit)
     for key in keys:
         code = FormulaCode(UserVariableAssignmentSig(),
                            key.domain,
                            self.space.flow,
                            lop=key,
                            rop=LiteralCode(None, key.domain,
                                            self.space.flow))
         unit = ScalarUnit(code, self.state.root, code.flow)
         zero_units.append(unit)
     tag = self.state.tag()
     routes = {}
     for unit in zero_units:
         routes[unit] = tag
     zero_term.routes = routes
     zero_term = PermanentTerm(tag, zero_term, zero_term.space,
                               zero_term.baseline, routes)
     filters = [
         FormulaCode(NoOpConditionSig(),
                     coerce(BooleanDomain()),
                     self.space.flow,
                     op=unit) for unit in zero_units
     ]
     filter = FormulaCode(AndSig(),
                          coerce(BooleanDomain()),
                          self.space.flow,
                          ops=filters)
     zero_term = FilterTerm(self.state.tag(), zero_term, filter,
                            zero_term.space, zero_term.baseline, {})
     term = JoinTerm(self.state.tag(), term, zero_term, [], False, False,
                     term.space, term.baseline, term.routes.copy())
     order = [(code, +1) for code in partition] + order
     term = OrderTerm(self.state.tag(), term, order, None, None, term.space,
                      term.baseline, term.routes.copy())
     term = PermanentTerm(self.state.tag(), term, term.space, term.baseline,
                          term.routes)
     next_units = []
     conditions = []
     for lop, rop in zip(keys, partition):
         condition = FormulaCode(IsEqualSig(+1),
                                 coerce(BooleanDomain()),
                                 self.space.flow,
                                 lop=lop,
                                 rop=rop)
         conditions.append(condition)
     if len(conditions) == 1:
         [condition] = conditions
     else:
         condition = FormulaCode(AndSig(),
                                 coerce(BooleanDomain()),
                                 self.space.flow,
                                 ops=conditions)
     one_literal = LiteralCode(1, coerce(IntegerDomain()), self.space.flow)
     on_true = FormulaCode(AddSig(),
                           coerce(IntegerDomain()),
                           self.space.flow,
                           lop=row_number,
                           rop=one_literal)
     on_false = one_literal
     value = FormulaCode(IfSig(),
                         row_number.domain,
                         self.space.flow,
                         condition=condition,
                         on_true=on_true,
                         on_false=on_false)
     code = FormulaCode(UserVariableAssignmentSig(),
                        row_number.domain,
                        self.space.flow,
                        lop=row_number,
                        rop=value)
     row_number_unit = ScalarUnit(code, term.space, code.flow)
     next_units.append(row_number_unit)
     for lop, rop in zip(keys, partition):
         code = FormulaCode(UserVariableAssignmentSig(),
                            lop.domain,
                            self.space.flow,
                            lop=lop,
                            rop=rop)
         unit = ScalarUnit(code, term.space, code.flow)
         next_units.append(unit)
     tag = self.state.tag()
     routes = term.routes.copy()
     for unit in next_units:
         routes[unit] = tag
     term = PermanentTerm(tag, term, term.space, term.baseline, routes)
     left_bound = 1
     if self.space.offset is not None:
         left_bound = self.space.offset + 1
     right_bound = left_bound + 1
     if self.space.limit is not None:
         right_bound = left_bound + self.space.limit
     left_bound_code = LiteralCode(left_bound, coerce(IntegerDomain()),
                                   term.space.flow)
     right_bound_code = LiteralCode(right_bound, coerce(IntegerDomain()),
                                    term.space.flow)
     left_filter = FormulaCode(CompareSig('>='),
                               coerce(BooleanDomain()),
                               term.space.flow,
                               lop=row_number_unit,
                               rop=left_bound_code)
     right_filter = FormulaCode(CompareSig('<'),
                                coerce(BooleanDomain()),
                                term.space.flow,
                                lop=row_number_unit,
                                rop=right_bound_code)
     filters = [left_filter, right_filter]
     filters += [
         FormulaCode(NoOpConditionSig(),
                     coerce(BooleanDomain()),
                     self.space.flow,
                     op=unit) for unit in next_units
     ]
     filter = FormulaCode(AndSig(),
                          coerce(BooleanDomain()),
                          self.space.flow,
                          ops=filters)
     term = FilterTerm(self.state.tag(), term, filter, term.space,
                       term.baseline, term.routes)
     return term
예제 #6
0
 def clip(self, term, order, partition):
     baseline = self.space.ground
     while not baseline.is_inflated:
         baseline = baseline.base
     kid = self.state.compile(self.space.seed, baseline=baseline)
     codes = [code for code, direction in order]
     codes += self.space.companions
     kid = self.state.inject(kid, codes)
     kid = WrapperTerm(self.state.tag(), kid, kid.space, kid.baseline,
                       kid.routes.copy())
     limit = self.space.limit
     if limit is None:
         limit = 1
     offset = self.space.offset
     key = []
     for code, direction in arrange(self.space.seed, with_strong=False):
         if all(self.space.base.spans(unit.space) for unit in code.units):
             continue
         key.append(code)
     assert key
     correlations = []
     filters = []
     for code in partition:
         correlations.append(code)
         lop = CorrelationCode(code)
         rop = code
         filter = FormulaCode(IsEqualSig(+1),
                              coerce(BooleanDomain()),
                              self.space.flow,
                              lop=lop,
                              rop=rop)
         filters.append(filter)
     if len(filters) == 0:
         filter = None
     elif len(filters) == 1:
         [filter] = filters
     else:
         filter = FormulaCode(AndSig(),
                              coerce(BooleanDomain()),
                              self.space.flow,
                              ops=filters)
     if filter is not None:
         kid = FilterTerm(self.state.tag(), kid, filter, kid.space,
                          kid.baseline, kid.routes.copy())
     kid = OrderTerm(self.state.tag(), kid, order, limit, offset, kid.space,
                     kid.baseline, kid.routes.copy())
     kid = CorrelationTerm(self.state.tag(), kid, kid.space, kid.baseline,
                           kid.routes.copy())
     if len(key) == 1:
         lop = rop = key[0]
         rop = ScalarUnit(rop, kid.space, kid.space.flow)
     else:
         filters = []
         for code in key:
             correlations.append(code)
             lop = CorrelationCode(code)
             rop = code
             filter = FormulaCode(IsEqualSig(+1),
                                  coerce(BooleanDomain()),
                                  self.space.flow,
                                  lop=lop,
                                  rop=rop)
             filters.append(filter)
         filter = FormulaCode(AndSig(),
                              coerce(BooleanDomain()),
                              self.space.flow,
                              ops=filters)
         lop = LiteralCode(True, coerce(BooleanDomain()), self.space.flow)
         rop = ScalarUnit(filter, kid.space, kid.space.flow)
     routes = term.routes.copy()
     routes[rop] = kid.tag
     kid = EmbeddingTerm(self.state.tag(), term, kid, correlations,
                         term.space, term.baseline, routes)
     filter = FormulaCode(IsAnySig(+1),
                          coerce(BooleanDomain()),
                          self.space.flow,
                          lop=lop,
                          rop=rop)
     return FilterTerm(self.state.tag(), kid, filter, kid.space,
                       kid.baseline, term.routes.copy())