def __new__( cls, left: 'Origin', right: 'Origin', condition: typing.Optional['series.Expression'] = None, kind: typing.Optional[typing.Union['Join.Kind', str]] = None, ): kind = cls.Kind(kind) if kind else cls.Kind.INNER if condition is not None else cls.Kind.CROSS if condition is not None: if kind is cls.Kind.CROSS: raise error.Syntax('Illegal use of condition for cross-join') condition = series.Cumulative.ensure_notin(series.Predicate.ensure_is(condition)) if not series.Element.dissect(condition).issubset(series.Element.dissect(*left.columns, *right.columns)): raise error.Syntax(f'({condition}) not a subset of source columns ({left.columns}, {right.columns})') return super().__new__(cls, left, right, condition, kind)
def make( cls, specs: typing.Sequence[ typing.Union[ Operable, typing.Union['Ordering.Direction', str], typing.Tuple[Operable, typing.Union['Ordering.Direction', str]], ] ], ) -> typing.Iterable['Ordering']: """Helper to generate orderings from given columns and directions. Args: specs: One or many columns or actual ordering instances. Returns: Sequence of ordering terms. """ specs = itertools.zip_longest(specs, specs[1:]) for column, direction in specs: if isinstance(column, Column): if isinstance(direction, (Ordering.Direction, str)): yield Ordering.Direction(direction)(column) next(specs) # pylint: disable=stop-iteration-return else: yield Ordering(column) elif isinstance(column, colabc.Sequence) and len(column) == 2: column, direction = column yield Ordering.Direction(direction)(column) else: raise error.Syntax('Expecting pair of column and direction')
def __new__(mcs, name: str, bases: typing.Tuple[typing.Type], namespace: typing.Dict[str, typing.Any]): existing = {s[k].name: k for s in bases if isinstance(s, Table.Schema) for k in s} for key, field in namespace.items(): if not isinstance(field, struct.Field): continue if not field.name: namespace[key] = field = field.renamed(key) # to normalize so that hash/eq is consistent if field.name in existing and field.name != existing[field.name]: raise error.Syntax(f'Colliding field name {field.name} in schema {name}') existing[field.name] = key return super().__new__(mcs, name, bases, namespace)
def ensure_subset(*columns: 'series.Column') -> typing.Sequence['series.Column']: """Ensure the provided columns is a valid subset of the available source columns. Args: *columns: List of columns to validate. Returns: Original list of columns if all valid. """ if not series.Element.dissect(*columns).issubset(superset): raise error.Syntax(f'{columns} not a subset of source columns: {superset}') return columns
def ensure_notin(cls, column: 'Column') -> 'Column': """Ensure given column is not composed of our type. Args: column: Column to be verified. Returns: Original column if not of our type or raising otherwise. """ if cls.dissect(column): raise error.Syntax(f'{cls.__name__} instance(s) found in {column}') return column
def ensure(cls, kind: 'Any') -> 'Any': """Ensure given kind is of our type. Args: kind: Kind to be verified. Returns: Original kind if instance of our type or raising otherwise. """ if not cls.match(kind): raise error.Syntax(f'{kind} not an instance of a {cls.__name__}') return kind
def ensure_is(cls, column: 'Column') -> 'Column': """Ensure given column is of our type. Args: column: Column to be verified. Returns: Original column if instance of our type or raising otherwise. """ column = cast(column) if not isinstance(column, cls): raise error.Syntax(f'{column} not an instance of a {cls.__name__}') return column
def ensure_is(cls: typing.Type[Operable], column: Operable) -> Operable: """Ensure given column is a predicate. Since this mixin class is supposed to be used as a first base class of its column implementors, this will mask the Column.ensure_is API. Here we add special implementation depending on whether it is used directly on the Predicate class or its bare mixin subclasses or the actual Column implementation using this mixin. Args: column: Column instance to be checked for its compliance. Returns: Column instance. """ column = Operable.ensure_is(column) if cls is Predicate: # bare Predicate - accept anything of a boolean kind. kindmod.Boolean.ensure(column.kind) elif not issubclass(cls, Column): # bare Predicate mixin subclasses if not isinstance(column, cls): raise error.Syntax(f'{column} not an instance of a {cls.__name__}') else: # defer to the column's .ensure_is implementation column = next(b for b in cls.__bases__ if issubclass(b, Column)).ensure_is(column) return column
def __init__(self, *operands: Operable): operands = [Operable.ensure_is(o) for o in operands] if not all(kindmod.Numeric.match(o.kind) for o in operands): raise error.Syntax(f'Invalid arithmetic operands for {self}')
def __init__(self, *operands: Operable): operands = [Operable.ensure_is(o) for o in operands] if not ( all(kindmod.Numeric.match(o.kind) for o in operands) or all(o.kind == operands[0].kind for o in operands) ): raise error.Syntax(f'Invalid operands for {self} comparison')