@@ -1002,6 +1002,12 @@ pub enum TableFactor {
1002
1002
partitions : Vec < Ident > ,
1003
1003
/// Optional PartiQL JsonPath: <https://partiql.org/dql/from.html>
1004
1004
json_path : Option < JsonPath > ,
1005
+ /// Optional table sample modifier
1006
+ /// See: <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#sample-clause>
1007
+ sample : Option < TableSample > ,
1008
+ /// Position of the table sample modifier in the table factor. Default is after the table alias
1009
+ /// e.g. `SELECT * FROM tbl t TABLESAMPLE (10 ROWS)`. See `Dialect::supports_table_sample_before_alias`.
1010
+ sample_before_alias : bool ,
1005
1011
} ,
1006
1012
Derived {
1007
1013
lateral : bool ,
@@ -1146,6 +1152,121 @@ pub enum TableFactor {
1146
1152
} ,
1147
1153
}
1148
1154
1155
+ /// The table sample modifier options
1156
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1157
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1158
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1159
+ pub enum TableSample {
1160
+ Bernoulli ( TableSampleBernoulli ) ,
1161
+ System ( TableSampleSystem ) ,
1162
+ Bucket ( TableSampleBucket ) ,
1163
+ Implicit ( TableSampleImplicit ) ,
1164
+ }
1165
+
1166
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1167
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1168
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1169
+ pub struct TableSampleBernoulli {
1170
+ pub probability : Option < Expr > ,
1171
+ pub value : Option < Expr > ,
1172
+ pub unit : Option < TableSampleUnit > ,
1173
+ }
1174
+
1175
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1176
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1177
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1178
+ pub struct TableSampleSystem {
1179
+ pub probability : Expr ,
1180
+ pub seed : Option < Expr > ,
1181
+ }
1182
+
1183
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1184
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1185
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1186
+ pub enum TableSampleUnit {
1187
+ Rows ,
1188
+ Percent ,
1189
+ }
1190
+
1191
+ impl fmt:: Display for TableSampleUnit {
1192
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1193
+ match self {
1194
+ TableSampleUnit :: Percent => write ! ( f, "PERCENT" ) ,
1195
+ TableSampleUnit :: Rows => write ! ( f, "ROWS" ) ,
1196
+ }
1197
+ }
1198
+ }
1199
+
1200
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1201
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1202
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1203
+ pub struct TableSampleBucket {
1204
+ pub bucket : Value ,
1205
+ pub total : Value ,
1206
+ pub on : Option < Expr > ,
1207
+ }
1208
+
1209
+ impl fmt:: Display for TableSampleBucket {
1210
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1211
+ write ! ( f, "BUCKET {} OUT OF {}" , self . bucket, self . total) ?;
1212
+ if let Some ( on) = & self . on {
1213
+ write ! ( f, " ON {}" , on) ?;
1214
+ }
1215
+ Ok ( ( ) )
1216
+ }
1217
+ }
1218
+
1219
+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1220
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1221
+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1222
+ pub struct TableSampleImplicit {
1223
+ pub value : Value ,
1224
+ pub unit : Option < TableSampleUnit > ,
1225
+ }
1226
+
1227
+ impl fmt:: Display for TableSampleImplicit {
1228
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1229
+ write ! ( f, "{}" , self . value) ?;
1230
+ if let Some ( unit) = & self . unit {
1231
+ write ! ( f, " {}" , unit) ?;
1232
+ }
1233
+ Ok ( ( ) )
1234
+ }
1235
+ }
1236
+
1237
+ impl fmt:: Display for TableSample {
1238
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1239
+ write ! ( f, " TABLESAMPLE" ) ?;
1240
+ match self {
1241
+ TableSample :: Bernoulli ( sample) => {
1242
+ write ! ( f, " BERNOULLI (" ) ?;
1243
+ if let Some ( probability) = & sample. probability {
1244
+ write ! ( f, "{})" , probability) ?;
1245
+ } else if let Some ( value) = & sample. value {
1246
+ write ! ( f, "{}" , value) ?;
1247
+ if let Some ( unit) = & sample. unit {
1248
+ write ! ( f, " {}" , unit) ?;
1249
+ }
1250
+ write ! ( f, ")" ) ?;
1251
+ }
1252
+ }
1253
+ TableSample :: System ( sample) => {
1254
+ write ! ( f, " SYSTEM ({})" , sample. probability) ?;
1255
+ if let Some ( seed) = & sample. seed {
1256
+ write ! ( f, " SEED ({})" , seed) ?;
1257
+ }
1258
+ }
1259
+ TableSample :: Bucket ( sample) => {
1260
+ write ! ( f, " ({})" , sample) ?;
1261
+ }
1262
+ TableSample :: Implicit ( sample) => {
1263
+ write ! ( f, " ({})" , sample) ?;
1264
+ }
1265
+ }
1266
+ Ok ( ( ) )
1267
+ }
1268
+ }
1269
+
1149
1270
/// The source of values in a `PIVOT` operation.
1150
1271
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1151
1272
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -1404,6 +1525,8 @@ impl fmt::Display for TableFactor {
1404
1525
partitions,
1405
1526
with_ordinality,
1406
1527
json_path,
1528
+ sample,
1529
+ sample_before_alias,
1407
1530
} => {
1408
1531
write ! ( f, "{name}" ) ?;
1409
1532
if let Some ( json_path) = json_path {
@@ -1426,6 +1549,9 @@ impl fmt::Display for TableFactor {
1426
1549
if * with_ordinality {
1427
1550
write ! ( f, " WITH ORDINALITY" ) ?;
1428
1551
}
1552
+ if let ( Some ( sample) , true ) = ( sample, sample_before_alias) {
1553
+ write ! ( f, "{sample}" ) ?;
1554
+ }
1429
1555
if let Some ( alias) = alias {
1430
1556
write ! ( f, " AS {alias}" ) ?;
1431
1557
}
@@ -1435,6 +1561,9 @@ impl fmt::Display for TableFactor {
1435
1561
if let Some ( version) = version {
1436
1562
write ! ( f, "{version}" ) ?;
1437
1563
}
1564
+ if let ( Some ( sample) , false ) = ( sample, sample_before_alias) {
1565
+ write ! ( f, "{sample}" ) ?;
1566
+ }
1438
1567
Ok ( ( ) )
1439
1568
}
1440
1569
TableFactor :: Derived {
0 commit comments