@@ -98,6 +98,8 @@ class RowOrdering:
98
98
"""Immutable object that holds information about the ordering of rows in a ArrayValue object. May not be unambiguous."""
99
99
100
100
ordering_value_columns : typing .Tuple [OrderingExpression , ...] = ()
101
+ integer_encoding : IntegerEncoding = IntegerEncoding (False )
102
+ string_encoding : StringEncoding = StringEncoding (False )
101
103
102
104
@property
103
105
def all_ordering_columns (self ) -> Sequence [OrderingExpression ]:
@@ -111,6 +113,20 @@ def referenced_columns(self) -> Set[str]:
111
113
for col in part .scalar_expression .unbound_variables
112
114
)
113
115
116
+ @property
117
+ def is_string_encoded (self ) -> bool :
118
+ """True if ordering is fully defined by a fixed length string column."""
119
+ return self .string_encoding .is_encoded
120
+
121
+ @property
122
+ def is_sequential (self ) -> bool :
123
+ return self .integer_encoding .is_encoded and self .integer_encoding .is_sequential
124
+
125
+ @property
126
+ def total_order_col (self ) -> Optional [OrderingExpression ]:
127
+ """Returns column id of columns that defines total ordering, if such as column exists"""
128
+ return None
129
+
114
130
def with_reverse (self ) -> RowOrdering :
115
131
"""Reverses the ordering."""
116
132
return RowOrdering (
@@ -121,17 +137,66 @@ def with_column_remap(self, mapping: typing.Mapping[str, str]) -> RowOrdering:
121
137
new_value_columns = [
122
138
col .remap_names (mapping ) for col in self .all_ordering_columns
123
139
]
124
- return TotalOrdering (
140
+ return RowOrdering (
125
141
tuple (new_value_columns ),
126
142
)
127
143
144
+ def with_non_sequential (self ):
145
+ """Create a copy that is marked as non-sequential.
146
+
147
+ This is useful when filtering, but not sorting, an expression.
148
+ """
149
+ if self .integer_encoding .is_sequential :
150
+ return RowOrdering (
151
+ self .ordering_value_columns ,
152
+ integer_encoding = IntegerEncoding (
153
+ self .integer_encoding .is_encoded , is_sequential = False
154
+ ),
155
+ )
156
+
157
+ return self
158
+
159
+ def with_ordering_columns (
160
+ self ,
161
+ ordering_value_columns : Sequence [OrderingExpression ] = (),
162
+ ) -> RowOrdering :
163
+ """Creates a new ordering that reorders by the given columns.
164
+
165
+ Args:
166
+ ordering_value_columns:
167
+ In decreasing precedence order, the values used to sort the ordering
168
+
169
+ Returns:
170
+ Modified ExpressionOrdering
171
+ """
172
+
173
+ # Truncate to remove any unneded col references after all total order cols included
174
+ new_ordering = self ._truncate_ordering (
175
+ (* ordering_value_columns , * self .ordering_value_columns )
176
+ )
177
+ return RowOrdering (
178
+ new_ordering ,
179
+ )
180
+
181
+ def _truncate_ordering (
182
+ self , order_refs : tuple [OrderingExpression , ...]
183
+ ) -> tuple [OrderingExpression , ...]:
184
+ # Truncate once we refer to a full key in bijective operations
185
+ columns_seen : Set [str ] = set ()
186
+ truncated_refs = []
187
+ for order_part in order_refs :
188
+ expr = order_part .scalar_expression
189
+ if not set (expr .unbound_variables ).issubset (columns_seen ):
190
+ if expr .is_bijective :
191
+ columns_seen .update (expr .unbound_variables )
192
+ truncated_refs .append (order_part )
193
+ return tuple (truncated_refs )
194
+
128
195
129
196
@dataclass (frozen = True )
130
197
class TotalOrdering (RowOrdering ):
131
198
"""Immutable object that holds information about the ordering of rows in a ArrayValue object. Guaranteed to be unambiguous."""
132
199
133
- integer_encoding : IntegerEncoding = IntegerEncoding (False )
134
- string_encoding : StringEncoding = StringEncoding (False )
135
200
# A table has a total ordering defined by the identities of a set of 1 or more columns.
136
201
# These columns must always be part of the ordering, in order to guarantee that the ordering is total.
137
202
# Therefore, any modifications(or drops) done to these columns must result in hidden copies being made.
@@ -234,15 +299,6 @@ def total_order_col(self) -> Optional[OrderingExpression]:
234
299
return None
235
300
return order_ref
236
301
237
- @property
238
- def is_string_encoded (self ) -> bool :
239
- """True if ordering is fully defined by a fixed length string column."""
240
- return self .string_encoding .is_encoded
241
-
242
- @property
243
- def is_sequential (self ) -> bool :
244
- return self .integer_encoding .is_encoded and self .integer_encoding .is_sequential
245
-
246
302
247
303
def encode_order_string (
248
304
order_id : ibis_types .IntegerColumn , length : int = DEFAULT_ORDERING_ID_LENGTH
0 commit comments