Skip to content

Commit 3ede8a8

Browse files
committed
Disallow repeat_row with WITH ORDINALITY
Also disallow it in constructs that are implemented by WITH ORDINALITY under the hood: - ROWS FROM - implicit ROWS FROM, i.e., multiple table functions in a SELECT clause
1 parent 571e1ef commit 3ede8a8

5 files changed

Lines changed: 38 additions & 33 deletions

File tree

src/expr/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub use interpret::{ColumnSpec, ColumnSpecs, Interpreter, ResultSpec, Trace, Tra
3333
pub use linear::plan::{MfpPlan, SafeMfpPlan};
3434
pub use linear::util::{join_permutations, permutation_for_arrangement};
3535
pub use linear::{MapFilterProject, memoize_expr};
36+
pub use relation::func::REPEAT_ROW_NAME;
3637
pub use relation::func::order_aggregate_datums as order_aggregate_datums_exported_for_benchmarking;
3738
pub use relation::func::{
3839
AggregateFunc, AnalyzedRegex, AnalyzedRegexOpts, CaptureGroupDesc, LagLeadType,

src/expr/src/relation/func.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3496,7 +3496,6 @@ impl TableFunc {
34963496
| TableFunc::GenerateSeriesTimestamp
34973497
| TableFunc::GenerateSeriesTimestampTz
34983498
| TableFunc::GuardSubquerySize { .. }
3499-
| TableFunc::RepeatRow // TODO: will move this to the not allowed category in the next commit
35003499
| TableFunc::RepeatRowNonNegative
35013500
| TableFunc::UnnestArray { .. }
35023501
| TableFunc::UnnestList { .. }
@@ -3507,9 +3506,13 @@ impl TableFunc {
35073506
| TableFunc::RegexpMatches => Some(TableFunc::WithOrdinality(WithOrdinality {
35083507
inner: Box::new(inner),
35093508
})),
3510-
// IMPORTANT: Before adding a new table function here, consider negative diffs:
3509+
// IMPORTANT: Before adding a new table function above, consider negative diffs:
35113510
// `WithOrdinality::eval` will panic if the inner table function emits a negative diff.
3512-
TableFunc::WithOrdinality(_) => None,
3511+
// (Note that negative diffs in the table function's _input_ don't matter. The table
3512+
// function implementation doesn't see the input diffs, so the thing that matters here
3513+
// is whether the table function itself can emit a negative diff.)
3514+
TableFunc::RepeatRow // can produce negative diffs
3515+
| TableFunc::WithOrdinality(_) => None, // no nesting of `WITH ORDINALITY` allowed
35133516
}
35143517
}
35153518
}
@@ -3882,7 +3885,7 @@ impl fmt::Display for TableFunc {
38823885
TableFunc::GenerateSeriesTimestampTz => f.write_str("generate_series"),
38833886
TableFunc::GenerateSubscriptsArray => f.write_str("generate_subscripts"),
38843887
TableFunc::GuardSubquerySize { .. } => f.write_str("guard_subquery_size"),
3885-
TableFunc::RepeatRow => f.write_str("repeat_row"),
3888+
TableFunc::RepeatRow => f.write_str(REPEAT_ROW_NAME),
38863889
TableFunc::RepeatRowNonNegative => f.write_str("repeat_row_non_negative"),
38873890
TableFunc::UnnestArray { .. } => f.write_str("unnest_array"),
38883891
TableFunc::UnnestList { .. } => f.write_str("unnest_list"),
@@ -3947,3 +3950,5 @@ impl WithOrdinality {
39473950
Ok(Box::new(it))
39483951
}
39493952
}
3953+
3954+
pub const REPEAT_ROW_NAME: &str = "repeat_row";

src/sql/src/func.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4733,7 +4733,7 @@ pub static MZ_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLoc
47334733
})
47344734
}) => ReturnType::set_of(RecordAny), oid::FUNC_REGEXP_EXTRACT_OID;
47354735
},
4736-
"repeat_row" => Table {
4736+
mz_expr::REPEAT_ROW_NAME => Table {
47374737
params!(Int64) => Operation::unary(move |ecx, n| {
47384738
ecx.require_feature_flag(&vars::ENABLE_REPEAT_ROW)?;
47394739
Ok(TableFuncPlan {

src/sql/src/plan/query.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ use mz_expr::func::variadic::{
5252
};
5353
use mz_expr::virtual_syntax::AlgExcept;
5454
use mz_expr::{
55-
Id, LetRecLimit, LocalId, MapFilterProject, MirScalarExpr, RowSetFinishing, TableFunc,
56-
func as expr_func,
55+
Id, LetRecLimit, LocalId, MapFilterProject, MirScalarExpr, REPEAT_ROW_NAME, RowSetFinishing,
56+
TableFunc, func as expr_func,
5757
};
5858
use mz_ore::assert_none;
5959
use mz_ore::collections::CollectionExt;
@@ -66,6 +66,7 @@ use mz_repr::adt::char::CharLength;
6666
use mz_repr::adt::numeric::{NUMERIC_DATUM_MAX_PRECISION, NumericMaxScale};
6767
use mz_repr::adt::timestamp::TimestampPrecision;
6868
use mz_repr::adt::varchar::VarCharMaxLength;
69+
use mz_repr::namespaces::MZ_CATALOG_SCHEMA;
6970
use mz_repr::{
7071
CatalogItemId, ColumnIndex, ColumnName, Datum, RelationDesc, RelationVersionSelector,
7172
ReprColumnType, Row, RowArena, SqlColumnType, SqlRelationType, SqlScalarType,
@@ -2826,6 +2827,14 @@ fn plan_scalar_table_funcs(
28262827
}
28272828
return Ok((expr, scope));
28282829
}
2830+
if table_funcs.keys().any(is_repeat_row) {
2831+
// Note: Would be also caught by WITH ORDINALITY checking for `repeat_row`, but then the
2832+
// error message would be misleading, because it would refer to WITH ORDINALITY.
2833+
bail_unsupported!(format!(
2834+
"{} in a SELECT clause with multiple table functions",
2835+
REPEAT_ROW_NAME
2836+
));
2837+
}
28292838
// Otherwise, plan as usual, emulating the ROWS FROM behavior
28302839
let (expr, mut scope, num_cols) =
28312840
plan_rows_from_internal(&rows_from_qcx, table_funcs.keys(), None)?;
@@ -3111,6 +3120,14 @@ fn plan_rows_from(
31113120
alias: Option<&TableAlias>,
31123121
with_ordinality: bool,
31133122
) -> Result<(HirRelationExpr, Scope), PlanError> {
3123+
// The `repeat_row` function is not supported in ROWS FROM.
3124+
if functions.iter().any(is_repeat_row) {
3125+
// Note: Would be also caught by WITH ORDINALITY checking for `repeat_row`, but then the
3126+
// error message would be misleading, because it would refer to WITH ORDINALITY instead of
3127+
// ROWS FROM.
3128+
bail_unsupported!(format!("{} in ROWS FROM", REPEAT_ROW_NAME));
3129+
}
3130+
31143131
// If there's only a single table function, planning proceeds as if `ROWS
31153132
// FROM` hadn't been written at all.
31163133
if let [function] = functions {
@@ -3155,6 +3172,10 @@ fn plan_rows_from(
31553172
Ok((expr, scope))
31563173
}
31573174

3175+
fn is_repeat_row(f: &Function<Aug>) -> bool {
3176+
f.name.full_name_str().as_str() == format!("{}.{}", MZ_CATALOG_SCHEMA, REPEAT_ROW_NAME)
3177+
}
3178+
31583179
/// Plans an expression coalescing multiple table functions. Each table
31593180
/// function is followed by its row ordinality. The entire expression is
31603181
/// followed by the coalesced row ordinality.

test/sqllogictest/table_func.slt

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -477,15 +477,8 @@ SELECT * FROM generate_series(0,3), repeat_row_non_negative(generate_series);
477477
3
478478
3
479479

480-
query II
480+
query error WITH ORDINALITY on repeat_row not yet supported
481481
SELECT * FROM generate_series(0,3), repeat_row(generate_series) WITH ORDINALITY;
482-
----
483-
1 1
484-
2 1
485-
2 2
486-
3 1
487-
3 2
488-
3 3
489482

490483
query II
491484
SELECT * FROM generate_series(0,3), repeat_row_non_negative(generate_series) WITH ORDINALITY;
@@ -497,13 +490,8 @@ SELECT * FROM generate_series(0,3), repeat_row_non_negative(generate_series) WIT
497490
3 2
498491
3 3
499492

500-
query II
493+
query error WITH ORDINALITY on repeat_row not yet supported
501494
SELECT * FROM generate_series(0,3), repeat_row(abs(generate_series - 1)) WITH ORDINALITY;
502-
----
503-
0 1
504-
2 1
505-
3 1
506-
3 2
507495

508496
query II
509497
SELECT * FROM generate_series(0,3), repeat_row_non_negative(abs(generate_series - 1)) WITH ORDINALITY;
@@ -842,21 +830,11 @@ SELECT jsonb_array_elements.generate_series FROM ROWS FROM (jsonb_array_elements
842830
generate_series
843831
1
844832

845-
query T colnames,rowsort
833+
query error repeat_row in ROWS FROM not yet supported
846834
SELECT repeat_row FROM ROWS FROM (repeat_row(2), generate_series(1, 1));
847-
----
848-
repeat_row
849-
()
850-
(1)
851835

852-
query TI
836+
query error repeat_row in a SELECT clause with multiple table functions not yet supported
853837
SELECT repeat_row(5), generate_series(1,2);
854-
----
855-
() NULL
856-
() NULL
857-
() NULL
858-
() 1
859-
() 2
860838

861839
query TI
862840
SELECT repeat_row_non_negative(5), generate_series(1,2);

0 commit comments

Comments
 (0)