diff --git a/src/generated/generated_temporal_udfs_0.cpp b/src/generated/generated_temporal_udfs_0.cpp index c939df0e..bb70a451 100644 --- a/src/generated/generated_temporal_udfs_0.cpp +++ b/src/generated/generated_temporal_udfs_0.cpp @@ -3106,6 +3106,285 @@ static void Gen_overlaps_spanset_spanset(DataChunk &args, ExpressionState &, Vec // ===== @ingroup meos_temporal_analytics_tile ===== +struct Split_temporal_time_split_0Info : public TableFunctionInfo { + Split_temporal_time_split_0Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_temporal_time_split_0State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + TimestampTz *b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_temporal_time_split_0State() { Release(); } +}; +static unique_ptr Split_temporal_time_split_0BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_temporal_time_split_0InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_temporal_time_split_0InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[4]; + idx_t r[4]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = temporal_time_split(t, MeosIntervalArg(UnifiedVectorFormat::GetData(u[1])[r[1]]), (k > 2 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[2])[r[2]]).value : timestamptz_in("2000-01-03", -1)), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : true), &st.b0, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + TimestampTz x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_temporal_time_split_0Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_temporal_time_split_0BindFn; + fn.init_local = Split_temporal_time_split_0InitFn; + fn.in_out_function = Split_temporal_time_split_0InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tbigint_value_split_1Info : public TableFunctionInfo { + Split_tbigint_value_split_1Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tbigint_value_split_1State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + int64_t *b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tbigint_value_split_1State() { Release(); } +}; +static unique_ptr Split_tbigint_value_split_1BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::BIGINT, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tbigint_value_split_1InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tbigint_value_split_1InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[4]; + idx_t r[4]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = tbigint_value_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], (k > 2 ? UnifiedVectorFormat::GetData(u[2])[r[2]] : 0), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : true), &st.b0, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + int64_t x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = (int64_t) x; + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tbigint_value_split_1Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tbigint_value_split_1BindFn; + fn.init_local = Split_tbigint_value_split_1InitFn; + fn.in_out_function = Split_tbigint_value_split_1InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tbigint_value_time_split_2Info : public TableFunctionInfo { + Split_tbigint_value_time_split_2Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tbigint_value_time_split_2State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + int64_t *b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tbigint_value_time_split_2State() { Release(); } +}; +static unique_ptr Split_tbigint_value_time_split_2BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::BIGINT, LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tbigint_value_time_split_2InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tbigint_value_time_split_2InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[6]; + idx_t r[6]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = tbigint_value_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], MeosIntervalArg(UnifiedVectorFormat::GetData(u[2])[r[2]]), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : 0), (k > 4 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[4])[r[4]]).value : timestamptz_in("2000-01-03", -1)), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), &st.b0, &st.b1, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + int64_t x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = (int64_t) x; + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tbigint_value_time_split_2Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tbigint_value_time_split_2BindFn; + fn.init_local = Split_tbigint_value_time_split_2InitFn; + fn.in_out_function = Split_tbigint_value_time_split_2InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + struct Tiles_tbigintbox_value_tiles_s0_a4Bind : public TableFunctionData { vector in; }; struct Tiles_tbigintbox_value_tiles_s0_a4State : public GlobalTableFunctionState { TBox *tiles = nullptr; int count = 0; idx_t idx = 0; @@ -3656,6 +3935,194 @@ static void Tiles_tbox_time_tiles_s0_a2ExecFn(ClientContext &, TableFunctionInpu output.SetCardinality(rows); } +struct Split_tfloat_value_split_3Info : public TableFunctionInfo { + Split_tfloat_value_split_3Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tfloat_value_split_3State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + double *b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tfloat_value_split_3State() { Release(); } +}; +static unique_ptr Split_tfloat_value_split_3BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::DOUBLE, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tfloat_value_split_3InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tfloat_value_split_3InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[4]; + idx_t r[4]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = tfloat_value_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], (k > 2 ? UnifiedVectorFormat::GetData(u[2])[r[2]] : 0.0), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : true), &st.b0, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + double x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = (double) x; + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tfloat_value_split_3Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tfloat_value_split_3BindFn; + fn.init_local = Split_tfloat_value_split_3InitFn; + fn.in_out_function = Split_tfloat_value_split_3InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tfloat_value_time_split_4Info : public TableFunctionInfo { + Split_tfloat_value_time_split_4Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tfloat_value_time_split_4State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + double *b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tfloat_value_time_split_4State() { Release(); } +}; +static unique_ptr Split_tfloat_value_time_split_4BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::DOUBLE, LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tfloat_value_time_split_4InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tfloat_value_time_split_4InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[6]; + idx_t r[6]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = tfloat_value_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], MeosIntervalArg(UnifiedVectorFormat::GetData(u[2])[r[2]]), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : 0.0), (k > 4 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[4])[r[4]]).value : timestamptz_in("2000-01-03", -1)), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), &st.b0, &st.b1, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + double x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = (double) x; + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tfloat_value_time_split_4Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tfloat_value_time_split_4BindFn; + fn.init_local = Split_tfloat_value_time_split_4InitFn; + fn.in_out_function = Split_tfloat_value_time_split_4InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + struct Tiles_tfloatbox_value_tiles_s0_a4Bind : public TableFunctionData { vector in; }; struct Tiles_tfloatbox_value_tiles_s0_a4State : public GlobalTableFunctionState { TBox *tiles = nullptr; int count = 0; idx_t idx = 0; @@ -3942,6 +4409,194 @@ static void Tiles_tfloatbox_value_time_tiles_s0_a3ExecFn(ClientContext &, TableF output.SetCardinality(rows); } +struct Split_tint_value_split_5Info : public TableFunctionInfo { + Split_tint_value_split_5Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tint_value_split_5State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + int *b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tint_value_split_5State() { Release(); } +}; +static unique_ptr Split_tint_value_split_5BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::INTEGER, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tint_value_split_5InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tint_value_split_5InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[4]; + idx_t r[4]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = tint_value_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], (k > 2 ? UnifiedVectorFormat::GetData(u[2])[r[2]] : 0), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : true), &st.b0, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + int x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = (int32_t) x; + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tint_value_split_5Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tint_value_split_5BindFn; + fn.init_local = Split_tint_value_split_5InitFn; + fn.in_out_function = Split_tint_value_split_5InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tint_value_time_split_6Info : public TableFunctionInfo { + Split_tint_value_time_split_6Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tint_value_time_split_6State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + int *b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tint_value_time_split_6State() { Release(); } +}; +static unique_ptr Split_tint_value_time_split_6BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {LogicalType::INTEGER, LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tint_value_time_split_6InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tint_value_time_split_6InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[6]; + idx_t r[6]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + st.parts = tint_value_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], MeosIntervalArg(UnifiedVectorFormat::GetData(u[2])[r[2]]), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : 0), (k > 4 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[4])[r[4]]).value : timestamptz_in("2000-01-03", -1)), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), &st.b0, &st.b1, &st.count); + free(t); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + int x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = (int32_t) x; + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tint_value_time_split_6Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tint_value_time_split_6BindFn; + fn.init_local = Split_tint_value_time_split_6InitFn; + fn.in_out_function = Split_tint_value_time_split_6InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + struct Tiles_tintbox_value_tiles_s0_a4Bind : public TableFunctionData { vector in; }; struct Tiles_tintbox_value_tiles_s0_a4State : public GlobalTableFunctionState { TBox *tiles = nullptr; int count = 0; idx_t idx = 0; @@ -5777,6 +6432,73 @@ void RegisterGenerated_meos_setspan_topo(ExtensionLoader &loader) { } void RegisterGenerated_meos_temporal_analytics_tile(ExtensionLoader &loader) { + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {CbufferTypes::tcbuffer(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), CbufferTypes::tcbuffer(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {CbufferTypes::tcbuffer(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), CbufferTypes::tcbuffer(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {CbufferTypes::tcbuffer(), LogicalType::INTERVAL}, nullptr), CbufferTypes::tcbuffer(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TGeometryTypes::tgeometry(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"time", "tgeom"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TGeometryTypes::tgeometry(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TGeometryTypes::tgeometry(), {"time", "tgeom"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TGeometryTypes::tgeometry(), LogicalType::INTERVAL}, nullptr), TGeometryTypes::tgeometry(), {"time", "tgeom"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TGeographyTypes::tgeography(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TGeographyTypes::tgeography(), {"time", "tgeog"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TGeographyTypes::tgeography(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TGeographyTypes::tgeography(), {"time", "tgeog"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TGeographyTypes::tgeography(), LogicalType::INTERVAL}, nullptr), TGeographyTypes::tgeography(), {"time", "tgeog"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TgeompointType::tgeompoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TgeompointType::tgeompoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TgeompointType::tgeompoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TgeompointType::tgeompoint(), LogicalType::INTERVAL}, nullptr), TgeompointType::tgeompoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TgeogpointType::tgeogpoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TgeogpointType::tgeogpoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TgeogpointType::tgeogpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TgeogpointType::tgeogpoint(), LogicalType::INTERVAL}, nullptr), TgeogpointType::tgeogpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {H3indexTypes::th3index(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), H3indexTypes::th3index(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {H3indexTypes::th3index(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), H3indexTypes::th3index(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {H3indexTypes::th3index(), LogicalType::INTERVAL}, nullptr), H3indexTypes::th3index(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TJsonbTypes::tjsonb(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TJsonbTypes::tjsonb(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TJsonbTypes::tjsonb(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TJsonbTypes::tjsonb(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TJsonbTypes::tjsonb(), LogicalType::INTERVAL}, nullptr), TJsonbTypes::tjsonb(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {NpointTypes::tnpoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), NpointTypes::tnpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {NpointTypes::tnpoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), NpointTypes::tnpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {NpointTypes::tnpoint(), LogicalType::INTERVAL}, nullptr), NpointTypes::tnpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TPcpointTypes::tpcpoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TPcpointTypes::tpcpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TPcpointTypes::tpcpoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TPcpointTypes::tpcpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TPcpointTypes::tpcpoint(), LogicalType::INTERVAL}, nullptr), TPcpointTypes::tpcpoint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TPcpatchTypes::tpcpatch(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TPcpatchTypes::tpcpatch(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TPcpatchTypes::tpcpatch(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TPcpatchTypes::tpcpatch(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TPcpatchTypes::tpcpatch(), LogicalType::INTERVAL}, nullptr), TPcpatchTypes::tpcpatch(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {PoseTypes::tpose(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), PoseTypes::tpose(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {PoseTypes::tpose(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), PoseTypes::tpose(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {PoseTypes::tpose(), LogicalType::INTERVAL}, nullptr), PoseTypes::tpose(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {PosechainTypes::tposechain(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), PosechainTypes::tposechain(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {PosechainTypes::tposechain(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), PosechainTypes::tposechain(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {PosechainTypes::tposechain(), LogicalType::INTERVAL}, nullptr), PosechainTypes::tposechain(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {QuadbinTypes::tquadbin(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), QuadbinTypes::tquadbin(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {QuadbinTypes::tquadbin(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), QuadbinTypes::tquadbin(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {QuadbinTypes::tquadbin(), LogicalType::INTERVAL}, nullptr), QuadbinTypes::tquadbin(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TrgeometryTypes::trgeometry(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TrgeometryTypes::trgeometry(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TrgeometryTypes::trgeometry(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TrgeometryTypes::trgeometry(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TrgeometryTypes::trgeometry(), LogicalType::INTERVAL}, nullptr), TrgeometryTypes::trgeometry(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {S2cellTypes::ts2cell(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), S2cellTypes::ts2cell(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {S2cellTypes::ts2cell(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), S2cellTypes::ts2cell(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {S2cellTypes::ts2cell(), LogicalType::INTERVAL}, nullptr), S2cellTypes::ts2cell(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tbool(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tbool(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tbool(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tbool(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tbool(), LogicalType::INTERVAL}, nullptr), TemporalTypes::tbool(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tint(), LogicalType::INTERVAL}, nullptr), TemporalTypes::tint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tbigint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tbigint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tbigint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tbigint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tbigint(), LogicalType::INTERVAL}, nullptr), TemporalTypes::tbigint(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tfloat(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tfloat(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tfloat(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tfloat(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::tfloat(), LogicalType::INTERVAL}, nullptr), TemporalTypes::tfloat(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::ttext(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::ttext(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::ttext(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::ttext(), {"time", "temp"})); + loader.RegisterFunction(Split_temporal_time_split_0Table(TableFunction("timeSplit", {TemporalTypes::ttext(), LogicalType::INTERVAL}, nullptr), TemporalTypes::ttext(), {"time", "temp"})); + loader.RegisterFunction(Split_tbigint_value_split_1Table(TableFunction("valueSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tbigint(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tbigint_value_split_1Table(TableFunction("valueSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT, LogicalType::BIGINT}, nullptr), TemporalTypes::tbigint(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tbigint_value_split_1Table(TableFunction("valueSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT}, nullptr), TemporalTypes::tbigint(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tbigint_value_time_split_2Table(TableFunction("valueTimeSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT, LogicalType::INTERVAL, LogicalType::BIGINT, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tbigint(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tbigint_value_time_split_2Table(TableFunction("valueTimeSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT, LogicalType::INTERVAL, LogicalType::BIGINT, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tbigint(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tbigint_value_time_split_2Table(TableFunction("valueTimeSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT, LogicalType::INTERVAL, LogicalType::BIGINT}, nullptr), TemporalTypes::tbigint(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tbigint_value_time_split_2Table(TableFunction("valueTimeSplit", {TemporalTypes::tbigint(), LogicalType::BIGINT, LogicalType::INTERVAL}, nullptr), TemporalTypes::tbigint(), {"number", "time", "tnumber"})); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::BIGINT, LogicalType::BIGINT, LogicalType::BOOLEAN}, Tiles_tbigintbox_value_tiles_s0_a4ExecFn, Tiles_tbigintbox_value_tiles_s0_a4BindFn, Tiles_tbigintbox_value_tiles_s0_a4InitFn)); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::BIGINT, LogicalType::BIGINT}, Tiles_tbigintbox_value_tiles_s0_a3ExecFn, Tiles_tbigintbox_value_tiles_s0_a3BindFn, Tiles_tbigintbox_value_tiles_s0_a3InitFn)); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::BIGINT}, Tiles_tbigintbox_value_tiles_s0_a2ExecFn, Tiles_tbigintbox_value_tiles_s0_a2BindFn, Tiles_tbigintbox_value_tiles_s0_a2InitFn)); @@ -5794,6 +6516,13 @@ void RegisterGenerated_meos_temporal_analytics_tile(ExtensionLoader &loader) { loader.RegisterFunction(TableFunction("timeTiles", {TboxType::tbox(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, Tiles_tbox_time_tiles_s0_a4ExecFn, Tiles_tbox_time_tiles_s0_a4BindFn, Tiles_tbox_time_tiles_s0_a4InitFn)); loader.RegisterFunction(TableFunction("timeTiles", {TboxType::tbox(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, Tiles_tbox_time_tiles_s0_a3ExecFn, Tiles_tbox_time_tiles_s0_a3BindFn, Tiles_tbox_time_tiles_s0_a3InitFn)); loader.RegisterFunction(TableFunction("timeTiles", {TboxType::tbox(), LogicalType::INTERVAL}, Tiles_tbox_time_tiles_s0_a2ExecFn, Tiles_tbox_time_tiles_s0_a2BindFn, Tiles_tbox_time_tiles_s0_a2InitFn)); + loader.RegisterFunction(Split_tfloat_value_split_3Table(TableFunction("valueSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tfloat(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tfloat_value_split_3Table(TableFunction("valueSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TemporalTypes::tfloat(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tfloat_value_split_3Table(TableFunction("valueSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE}, nullptr), TemporalTypes::tfloat(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tfloat_value_time_split_4Table(TableFunction("valueTimeSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE, LogicalType::INTERVAL, LogicalType::DOUBLE, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tfloat(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tfloat_value_time_split_4Table(TableFunction("valueTimeSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE, LogicalType::INTERVAL, LogicalType::DOUBLE, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tfloat(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tfloat_value_time_split_4Table(TableFunction("valueTimeSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE, LogicalType::INTERVAL, LogicalType::DOUBLE}, nullptr), TemporalTypes::tfloat(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tfloat_value_time_split_4Table(TableFunction("valueTimeSplit", {TemporalTypes::tfloat(), LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TemporalTypes::tfloat(), {"number", "time", "tnumber"})); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::BOOLEAN}, Tiles_tfloatbox_value_tiles_s0_a4ExecFn, Tiles_tfloatbox_value_tiles_s0_a4BindFn, Tiles_tfloatbox_value_tiles_s0_a4InitFn)); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::DOUBLE, LogicalType::DOUBLE}, Tiles_tfloatbox_value_tiles_s0_a3ExecFn, Tiles_tfloatbox_value_tiles_s0_a3BindFn, Tiles_tfloatbox_value_tiles_s0_a3InitFn)); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::DOUBLE}, Tiles_tfloatbox_value_tiles_s0_a2ExecFn, Tiles_tfloatbox_value_tiles_s0_a2BindFn, Tiles_tfloatbox_value_tiles_s0_a2InitFn)); @@ -5801,6 +6530,13 @@ void RegisterGenerated_meos_temporal_analytics_tile(ExtensionLoader &loader) { loader.RegisterFunction(TableFunction("valueTimeTiles", {TboxType::tbox(), LogicalType::DOUBLE, LogicalType::INTERVAL, LogicalType::DOUBLE, LogicalType::TIMESTAMP_TZ}, Tiles_tfloatbox_value_time_tiles_s0_a5ExecFn, Tiles_tfloatbox_value_time_tiles_s0_a5BindFn, Tiles_tfloatbox_value_time_tiles_s0_a5InitFn)); loader.RegisterFunction(TableFunction("valueTimeTiles", {TboxType::tbox(), LogicalType::DOUBLE, LogicalType::INTERVAL, LogicalType::DOUBLE}, Tiles_tfloatbox_value_time_tiles_s0_a4ExecFn, Tiles_tfloatbox_value_time_tiles_s0_a4BindFn, Tiles_tfloatbox_value_time_tiles_s0_a4InitFn)); loader.RegisterFunction(TableFunction("valueTimeTiles", {TboxType::tbox(), LogicalType::DOUBLE, LogicalType::INTERVAL}, Tiles_tfloatbox_value_time_tiles_s0_a3ExecFn, Tiles_tfloatbox_value_time_tiles_s0_a3BindFn, Tiles_tfloatbox_value_time_tiles_s0_a3InitFn)); + loader.RegisterFunction(Split_tint_value_split_5Table(TableFunction("valueSplit", {TemporalTypes::tint(), LogicalType::INTEGER, LogicalType::INTEGER, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tint(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tint_value_split_5Table(TableFunction("valueSplit", {TemporalTypes::tint(), LogicalType::INTEGER, LogicalType::INTEGER}, nullptr), TemporalTypes::tint(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tint_value_split_5Table(TableFunction("valueSplit", {TemporalTypes::tint(), LogicalType::INTEGER}, nullptr), TemporalTypes::tint(), {"number", "tnumber"})); + loader.RegisterFunction(Split_tint_value_time_split_6Table(TableFunction("valueTimeSplit", {TemporalTypes::tint(), LogicalType::INTEGER, LogicalType::INTERVAL, LogicalType::INTEGER, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TemporalTypes::tint(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tint_value_time_split_6Table(TableFunction("valueTimeSplit", {TemporalTypes::tint(), LogicalType::INTEGER, LogicalType::INTERVAL, LogicalType::INTEGER, LogicalType::TIMESTAMP_TZ}, nullptr), TemporalTypes::tint(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tint_value_time_split_6Table(TableFunction("valueTimeSplit", {TemporalTypes::tint(), LogicalType::INTEGER, LogicalType::INTERVAL, LogicalType::INTEGER}, nullptr), TemporalTypes::tint(), {"number", "time", "tnumber"})); + loader.RegisterFunction(Split_tint_value_time_split_6Table(TableFunction("valueTimeSplit", {TemporalTypes::tint(), LogicalType::INTEGER, LogicalType::INTERVAL}, nullptr), TemporalTypes::tint(), {"number", "time", "tnumber"})); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::INTEGER, LogicalType::INTEGER, LogicalType::BOOLEAN}, Tiles_tintbox_value_tiles_s0_a4ExecFn, Tiles_tintbox_value_tiles_s0_a4BindFn, Tiles_tintbox_value_tiles_s0_a4InitFn)); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::INTEGER, LogicalType::INTEGER}, Tiles_tintbox_value_tiles_s0_a3ExecFn, Tiles_tintbox_value_tiles_s0_a3BindFn, Tiles_tintbox_value_tiles_s0_a3InitFn)); loader.RegisterFunction(TableFunction("valueTiles", {TboxType::tbox(), LogicalType::INTEGER}, Tiles_tintbox_value_tiles_s0_a2ExecFn, Tiles_tintbox_value_tiles_s0_a2BindFn, Tiles_tintbox_value_tiles_s0_a2InitFn)); diff --git a/src/generated/generated_temporal_udfs_5.cpp b/src/generated/generated_temporal_udfs_5.cpp index 9f14d10d..4afc0e9f 100644 --- a/src/generated/generated_temporal_udfs_5.cpp +++ b/src/generated/generated_temporal_udfs_5.cpp @@ -3491,6 +3491,1170 @@ static void Tiles_stbox_time_tiles_s0_a2ExecFn(ClientContext &, TableFunctionInp output.SetCardinality(rows); } +struct Split_tgeo_space_split_7Info : public TableFunctionInfo { + Split_tgeo_space_split_7Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_split_7State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_split_7State() { Release(); } +}; +static unique_ptr Split_tgeo_space_split_7BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_split_7InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_split_7InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[7]; + idx_t r[7]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g4 = (k > 4 ? GeometryToGSerialized(UnifiedVectorFormat::GetData(u[4])[r[4]], 0) : geom_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], UnifiedVectorFormat::GetData(u[3])[r[3]], g4, (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), (k > 6 ? UnifiedVectorFormat::GetData(u[6])[r[6]] : true), &st.b0, &st.count); + free(t); free(g4); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_split_7Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_split_7BindFn; + fn.init_local = Split_tgeo_space_split_7InitFn; + fn.in_out_function = Split_tgeo_space_split_7InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_split_8Info : public TableFunctionInfo { + Split_tgeo_space_split_8Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_split_8State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_split_8State() { Release(); } +}; +static unique_ptr Split_tgeo_space_split_8BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_split_8InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_split_8InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[5]; + idx_t r[5]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g2 = (k > 2 ? GeometryToGSerialized(UnifiedVectorFormat::GetData(u[2])[r[2]], 0) : geom_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], 0, 0, g2, (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : true), (k > 4 ? UnifiedVectorFormat::GetData(u[4])[r[4]] : true), &st.b0, &st.count); + free(t); free(g2); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_split_8Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_split_8BindFn; + fn.init_local = Split_tgeo_space_split_8InitFn; + fn.in_out_function = Split_tgeo_space_split_8InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_split_9Info : public TableFunctionInfo { + Split_tgeo_space_split_9Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_split_9State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_split_9State() { Release(); } +}; +static unique_ptr Split_tgeo_space_split_9BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_split_9InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_split_9InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[6]; + idx_t r[6]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g3 = (k > 3 ? GeometryToGSerialized(UnifiedVectorFormat::GetData(u[3])[r[3]], 0) : geom_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], 0, g3, (k > 4 ? UnifiedVectorFormat::GetData(u[4])[r[4]] : true), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), &st.b0, &st.count); + free(t); free(g3); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_split_9Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_split_9BindFn; + fn.init_local = Split_tgeo_space_split_9InitFn; + fn.in_out_function = Split_tgeo_space_split_9InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_split_10Info : public TableFunctionInfo { + Split_tgeo_space_split_10Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_split_10State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_split_10State() { Release(); } +}; +static unique_ptr Split_tgeo_space_split_10BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_split_10InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_split_10InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[7]; + idx_t r[7]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g4 = (k > 4 ? GeogFromGeometry(UnifiedVectorFormat::GetData(u[4])[r[4]]) : geog_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], UnifiedVectorFormat::GetData(u[3])[r[3]], g4, (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), (k > 6 ? UnifiedVectorFormat::GetData(u[6])[r[6]] : true), &st.b0, &st.count); + free(t); free(g4); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_split_10Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_split_10BindFn; + fn.init_local = Split_tgeo_space_split_10InitFn; + fn.in_out_function = Split_tgeo_space_split_10InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_split_11Info : public TableFunctionInfo { + Split_tgeo_space_split_11Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_split_11State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_split_11State() { Release(); } +}; +static unique_ptr Split_tgeo_space_split_11BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_split_11InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_split_11InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[5]; + idx_t r[5]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g2 = (k > 2 ? GeogFromGeometry(UnifiedVectorFormat::GetData(u[2])[r[2]]) : geog_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], 0, 0, g2, (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : true), (k > 4 ? UnifiedVectorFormat::GetData(u[4])[r[4]] : true), &st.b0, &st.count); + free(t); free(g2); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_split_11Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_split_11BindFn; + fn.init_local = Split_tgeo_space_split_11InitFn; + fn.in_out_function = Split_tgeo_space_split_11InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_split_12Info : public TableFunctionInfo { + Split_tgeo_space_split_12Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_split_12State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); + parts = nullptr; b0 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_split_12State() { Release(); } +}; +static unique_ptr Split_tgeo_space_split_12BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_split_12InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_split_12InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[6]; + idx_t r[6]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g3 = (k > 3 ? GeogFromGeometry(UnifiedVectorFormat::GetData(u[3])[r[3]]) : geog_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], 0, g3, (k > 4 ? UnifiedVectorFormat::GetData(u[4])[r[4]] : true), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), &st.b0, &st.count); + free(t); free(g3); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_split_12Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_split_12BindFn; + fn.init_local = Split_tgeo_space_split_12InitFn; + fn.in_out_function = Split_tgeo_space_split_12InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_time_split_13Info : public TableFunctionInfo { + Split_tgeo_space_time_split_13Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_time_split_13State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_time_split_13State() { Release(); } +}; +static unique_ptr Split_tgeo_space_time_split_13BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_time_split_13InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_time_split_13InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[9]; + idx_t r[9]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g5 = (k > 5 ? GeometryToGSerialized(UnifiedVectorFormat::GetData(u[5])[r[5]], 0) : geom_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], UnifiedVectorFormat::GetData(u[3])[r[3]], MeosIntervalArg(UnifiedVectorFormat::GetData(u[4])[r[4]]), g5, (k > 6 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[6])[r[6]]).value : timestamptz_in("2000-01-03", -1)), (k > 7 ? UnifiedVectorFormat::GetData(u[7])[r[7]] : true), (k > 8 ? UnifiedVectorFormat::GetData(u[8])[r[8]] : true), &st.b0, &st.b1, &st.count); + free(t); free(g5); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_time_split_13Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_time_split_13BindFn; + fn.init_local = Split_tgeo_space_time_split_13InitFn; + fn.in_out_function = Split_tgeo_space_time_split_13InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_time_split_14Info : public TableFunctionInfo { + Split_tgeo_space_time_split_14Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_time_split_14State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_time_split_14State() { Release(); } +}; +static unique_ptr Split_tgeo_space_time_split_14BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_time_split_14InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_time_split_14InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[7]; + idx_t r[7]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g3 = (k > 3 ? GeometryToGSerialized(UnifiedVectorFormat::GetData(u[3])[r[3]], 0) : geom_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], 0, 0, MeosIntervalArg(UnifiedVectorFormat::GetData(u[2])[r[2]]), g3, (k > 4 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[4])[r[4]]).value : timestamptz_in("2000-01-03", -1)), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), (k > 6 ? UnifiedVectorFormat::GetData(u[6])[r[6]] : true), &st.b0, &st.b1, &st.count); + free(t); free(g3); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_time_split_14Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_time_split_14BindFn; + fn.init_local = Split_tgeo_space_time_split_14InitFn; + fn.in_out_function = Split_tgeo_space_time_split_14InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_time_split_15Info : public TableFunctionInfo { + Split_tgeo_space_time_split_15Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_time_split_15State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_time_split_15State() { Release(); } +}; +static unique_ptr Split_tgeo_space_time_split_15BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_time_split_15InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_time_split_15InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[8]; + idx_t r[8]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g4 = (k > 4 ? GeometryToGSerialized(UnifiedVectorFormat::GetData(u[4])[r[4]], 0) : geom_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], 0, MeosIntervalArg(UnifiedVectorFormat::GetData(u[3])[r[3]]), g4, (k > 5 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[5])[r[5]]).value : timestamptz_in("2000-01-03", -1)), (k > 6 ? UnifiedVectorFormat::GetData(u[6])[r[6]] : true), (k > 7 ? UnifiedVectorFormat::GetData(u[7])[r[7]] : true), &st.b0, &st.b1, &st.count); + free(t); free(g4); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_time_split_15Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_time_split_15BindFn; + fn.init_local = Split_tgeo_space_time_split_15InitFn; + fn.in_out_function = Split_tgeo_space_time_split_15InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_time_split_16Info : public TableFunctionInfo { + Split_tgeo_space_time_split_16Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_time_split_16State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_time_split_16State() { Release(); } +}; +static unique_ptr Split_tgeo_space_time_split_16BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_time_split_16InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_time_split_16InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[9]; + idx_t r[9]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g5 = (k > 5 ? GeogFromGeometry(UnifiedVectorFormat::GetData(u[5])[r[5]]) : geog_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], UnifiedVectorFormat::GetData(u[3])[r[3]], MeosIntervalArg(UnifiedVectorFormat::GetData(u[4])[r[4]]), g5, (k > 6 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[6])[r[6]]).value : timestamptz_in("2000-01-03", -1)), (k > 7 ? UnifiedVectorFormat::GetData(u[7])[r[7]] : true), (k > 8 ? UnifiedVectorFormat::GetData(u[8])[r[8]] : true), &st.b0, &st.b1, &st.count); + free(t); free(g5); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_time_split_16Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_time_split_16BindFn; + fn.init_local = Split_tgeo_space_time_split_16InitFn; + fn.in_out_function = Split_tgeo_space_time_split_16InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_time_split_17Info : public TableFunctionInfo { + Split_tgeo_space_time_split_17Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_time_split_17State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_time_split_17State() { Release(); } +}; +static unique_ptr Split_tgeo_space_time_split_17BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_time_split_17InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_time_split_17InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[7]; + idx_t r[7]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g3 = (k > 3 ? GeogFromGeometry(UnifiedVectorFormat::GetData(u[3])[r[3]]) : geog_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], 0, 0, MeosIntervalArg(UnifiedVectorFormat::GetData(u[2])[r[2]]), g3, (k > 4 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[4])[r[4]]).value : timestamptz_in("2000-01-03", -1)), (k > 5 ? UnifiedVectorFormat::GetData(u[5])[r[5]] : true), (k > 6 ? UnifiedVectorFormat::GetData(u[6])[r[6]] : true), &st.b0, &st.b1, &st.count); + free(t); free(g3); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_time_split_17Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_time_split_17BindFn; + fn.init_local = Split_tgeo_space_time_split_17InitFn; + fn.in_out_function = Split_tgeo_space_time_split_17InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + +struct Split_tgeo_space_time_split_18Info : public TableFunctionInfo { + Split_tgeo_space_time_split_18Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {} + LogicalType ttype; + vector names; +}; +struct Split_tgeo_space_time_split_18State : public LocalTableFunctionState { + Temporal **parts = nullptr; int count = 0; int idx = 0; + GSERIALIZED **b0 = nullptr; + TimestampTz *b1 = nullptr; + idx_t row = 0; bool loaded = false; + void Release() { + for (int k = idx; k < count; k++) { + free(parts[k]); + free(b0[k]); + } + free(parts); free(b0); free(b1); + parts = nullptr; b0 = nullptr; b1 = nullptr; count = 0; idx = 0; + } + ~Split_tgeo_space_time_split_18State() { Release(); } +}; +static unique_ptr Split_tgeo_space_time_split_18BindFn(ClientContext &, TableFunctionBindInput &input, + vector &types, vector &names) { + auto &info = input.info->Cast(); + types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, info.ttype}; + names = info.names; + return make_uniq(); +} +static unique_ptr Split_tgeo_space_time_split_18InitFn(ExecutionContext &context, TableFunctionInitInput &, + GlobalTableFunctionState *) { + EnsureMeosThreadInitialized(context.client); + return make_uniq(); +} +static OperatorResultType Split_tgeo_space_time_split_18InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input, + DataChunk &output) { + auto &st = data.local_state->Cast(); + ArenaAllocator arena(Allocator::DefaultAllocator()); + idx_t i = 0; + while (i < STANDARD_VECTOR_SIZE) { + if (!st.loaded) { + if (st.row >= input.size()) { + if (i > 0) { + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; + } + st.row = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + const idx_t k = input.ColumnCount(); + UnifiedVectorFormat u[8]; + idx_t r[8]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + input.data[c].ToUnifiedFormat(input.size(), u[c]); + r[c] = u[c].sel->get_index(st.row); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (valid) { + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + GSERIALIZED *g4 = (k > 4 ? GeogFromGeometry(UnifiedVectorFormat::GetData(u[4])[r[4]]) : geog_in("Point(0 0 0)", -1)); + st.parts = tgeo_space_time_split(t, UnifiedVectorFormat::GetData(u[1])[r[1]], UnifiedVectorFormat::GetData(u[2])[r[2]], 0, MeosIntervalArg(UnifiedVectorFormat::GetData(u[3])[r[3]]), g4, (k > 5 ? DuckDBToMeosTimestamp(UnifiedVectorFormat::GetData(u[5])[r[5]]).value : timestamptz_in("2000-01-03", -1)), (k > 6 ? UnifiedVectorFormat::GetData(u[6])[r[6]] : true), (k > 7 ? UnifiedVectorFormat::GetData(u[7])[r[7]] : true), &st.b0, &st.b1, &st.count); + free(t); free(g4); + if (!st.parts) st.count = 0; + } + st.loaded = true; + } + if (st.idx >= st.count) { + st.Release(); + st.loaded = false; + st.row++; + continue; + } + { + auto &v = output.data[0]; + GSERIALIZED *x = st.b0[st.idx]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x); + } + { + auto &v = output.data[1]; + TimestampTz x = st.b1[st.idx]; + FlatVector::GetData(v)[i] = TakeTimestamp(x); + } + { + auto &v = output.data[2]; + Temporal *x = st.parts[st.idx]; + FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, temporal_mem_size(x)); + free(x); + } + st.idx++; i++; + } + output.SetCardinality(i); + return OperatorResultType::HAVE_MORE_OUTPUT; +} +static TableFunction Split_tgeo_space_time_split_18Table(TableFunction fn, const LogicalType &t, vector names) { + fn.bind = Split_tgeo_space_time_split_18BindFn; + fn.init_local = Split_tgeo_space_time_split_18InitFn; + fn.in_out_function = Split_tgeo_space_time_split_18InOutFn; + fn.function_info = make_shared_ptr(t, std::move(names)); + return fn; +} + static void Gen_tgeo_time_boxes(DataChunk &args, ExpressionState &, Vector &result) { EnsureMeosThreadInitialized(); auto &in_vec = args.data[0]; @@ -7538,6 +8702,87 @@ void RegisterGenerated_meos_geo_tile(ExtensionLoader &loader) { loader.RegisterFunction(TableFunction("timeTiles", {StboxType::stbox(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, Tiles_stbox_time_tiles_s0_a4ExecFn, Tiles_stbox_time_tiles_s0_a4BindFn, Tiles_stbox_time_tiles_s0_a4InitFn)); loader.RegisterFunction(TableFunction("timeTiles", {StboxType::stbox(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, Tiles_stbox_time_tiles_s0_a3ExecFn, Tiles_stbox_time_tiles_s0_a3BindFn, Tiles_stbox_time_tiles_s0_a3InitFn)); loader.RegisterFunction(TableFunction("timeTiles", {StboxType::stbox(), LogicalType::INTERVAL}, Tiles_stbox_time_tiles_s0_a2ExecFn, Tiles_stbox_time_tiles_s0_a2BindFn, Tiles_stbox_time_tiles_s0_a2InitFn)); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TGeometryTypes::tgeometry(), {"point", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_7Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_8Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_9Table(TableFunction("spaceSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TgeompointType::tgeompoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_10Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_10Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_10Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_10Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_11Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_11Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_11Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_11Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_12Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_12Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType(), LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_12Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, MobilityDuckGeometryType()}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_split_12Table(TableFunction("spaceSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE}, nullptr), TgeogpointType::tgeogpoint(), {"point", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TGeometryTypes::tgeometry(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TGeometryTypes::tgeometry(), {"point", "time", "tgeo"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_13Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_14Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_15Table(TableFunction("spaceTimeSplit", {TgeompointType::tgeompoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TgeompointType::tgeompoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_16Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_16Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_16Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_16Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_16Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_17Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_17Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_17Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_17Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_17Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_18Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_18Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_18Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_18Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL, MobilityDuckGeometryType()}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); + loader.RegisterFunction(Split_tgeo_space_time_split_18Table(TableFunction("spaceTimeSplit", {TgeogpointType::tgeogpoint(), LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::INTERVAL}, nullptr), TgeogpointType::tgeogpoint(), {"point", "time", "tpoint"})); RegisterSerializedScalarFunction(loader, ScalarFunction("timeBoxes", {TGeometryTypes::tgeometry(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, LogicalType::LIST(StboxType::stbox()), Gen_tgeo_time_boxes)); RegisterSerializedScalarFunction(loader, ScalarFunction("timeBoxes", {TgeompointType::tgeompoint(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::BOOLEAN, LogicalType::BOOLEAN}, LogicalType::LIST(StboxType::stbox()), Gen_tgeo_time_boxes)); RegisterSerializedScalarFunction(loader, ScalarFunction("timeBoxes", {TGeometryTypes::tgeometry(), LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, LogicalType::LIST(StboxType::stbox()), Gen_tgeo_time_boxes_bitmatrix_border_inc)); diff --git a/src/generated/generated_temporal_udfs_9.cpp b/src/generated/generated_temporal_udfs_9.cpp index d3db801c..e858b01a 100644 --- a/src/generated/generated_temporal_udfs_9.cpp +++ b/src/generated/generated_temporal_udfs_9.cpp @@ -1564,6 +1564,53 @@ static void Gen_tgeompoint_to_tgeometry(DataChunk &args, ExpressionState &, Vect }); } +static void Gen_tpoint_as_mvtgeom_row0(DataChunk &args, ExpressionState &, Vector &result) { + EnsureMeosThreadInitialized(); + const idx_t rows = args.size(), k = args.ColumnCount(); + UnifiedVectorFormat u[5]; + for (idx_t c = 0; c < k; c++) args.data[c].ToUnifiedFormat(rows, u[c]); + result.SetVectorType(VectorType::FLAT_VECTOR); + auto &cols = StructVector::GetEntries(result); + auto &valid_out = FlatVector::Validity(result); + ArenaAllocator arena(Allocator::DefaultAllocator()); + for (idx_t i = 0; i < rows; i++) { + idx_t r[5]; + bool valid = true; + for (idx_t c = 0; c < k; c++) { + r[c] = u[c].sel->get_index(i); + valid = valid && u[c].validity.RowIsValid(r[c]); + } + if (!valid) { valid_out.SetInvalid(i); FlatVector::GetData(*cols[1])[i] = list_entry_t{ListVector::GetListSize(*cols[1]), 0}; continue; } + Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]); + auto *x1 = BlobToStbox(UnifiedVectorFormat::GetData(u[1])[r[1]]); + GSERIALIZED *o_gsarr = nullptr; + int64_t *o_timesarr = nullptr; + int o_count = 0; + bool found = tpoint_as_mvtgeom(t, x1, (k > 2 ? UnifiedVectorFormat::GetData(u[2])[r[2]] : 4096), (k > 3 ? UnifiedVectorFormat::GetData(u[3])[r[3]] : 256), (k > 4 ? UnifiedVectorFormat::GetData(u[4])[r[4]] : true), &o_gsarr, &o_timesarr, &o_count); + free(t); free(x1); + if (!found || !o_gsarr) { + valid_out.SetInvalid(i); free(o_gsarr); free(o_timesarr); FlatVector::GetData(*cols[1])[i] = list_entry_t{ListVector::GetListSize(*cols[1]), 0}; + continue; + } + { + auto &v = *cols[0]; + FlatVector::GetData(v)[i] = GSerializedToGeometry(o_gsarr, arena, v); + free(o_gsarr); + } + { + auto &v = *cols[1]; + idx_t off = ListVector::GetListSize(v); + ListVector::Reserve(v, off + o_count); + auto d = FlatVector::GetData(ListVector::GetEntry(v)); + for (int e = 0; e < o_count; e++) d[off + e] = (int64_t) o_timesarr[e]; + FlatVector::GetData(v)[i] = list_entry_t{off, (idx_t) o_count}; + ListVector::SetListSize(v, off + o_count); + free(o_timesarr); + } + } + if (args.AllConstant()) result.SetVectorType(VectorType::CONSTANT_VECTOR); +} + static void Gen_tpoint_tfloat_to_geomeas(DataChunk &args, ExpressionState &state, Vector &result) { EnsureMeosThreadInitialized(); const idx_t rows = args.size(); @@ -3103,6 +3150,10 @@ void RegisterGenerated_meos_geo_conversion(ExtensionLoader &loader) { RegisterSerializedScalarFunction(loader, ScalarFunction("tgeogpoint", {TgeompointType::tgeompoint()}, TgeogpointType::tgeogpoint(), Gen_tgeompoint_to_tgeogpoint)); RegisterSerializedScalarFunction(loader, ScalarFunction("tgeompoint", {TGeometryTypes::tgeometry()}, TgeompointType::tgeompoint(), Gen_tgeometry_to_tgeompoint)); RegisterSerializedScalarFunction(loader, ScalarFunction("tgeometry", {TgeompointType::tgeompoint()}, TGeometryTypes::tgeometry(), Gen_tgeompoint_to_tgeometry)); + RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {TgeompointType::tgeompoint(), StboxType::stbox(), LogicalType::INTEGER, LogicalType::INTEGER, LogicalType::BOOLEAN}, LogicalType::STRUCT({{"geom", MobilityDuckGeometryType()}, {"times", LogicalType::LIST(LogicalType::BIGINT)}}), Gen_tpoint_as_mvtgeom_row0)); + RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {TgeompointType::tgeompoint(), StboxType::stbox(), LogicalType::INTEGER, LogicalType::INTEGER}, LogicalType::STRUCT({{"geom", MobilityDuckGeometryType()}, {"times", LogicalType::LIST(LogicalType::BIGINT)}}), Gen_tpoint_as_mvtgeom_row0)); + RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {TgeompointType::tgeompoint(), StboxType::stbox(), LogicalType::INTEGER}, LogicalType::STRUCT({{"geom", MobilityDuckGeometryType()}, {"times", LogicalType::LIST(LogicalType::BIGINT)}}), Gen_tpoint_as_mvtgeom_row0)); + RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {TgeompointType::tgeompoint(), StboxType::stbox()}, LogicalType::STRUCT({{"geom", MobilityDuckGeometryType()}, {"times", LogicalType::LIST(LogicalType::BIGINT)}}), Gen_tpoint_as_mvtgeom_row0)); RegisterSerializedScalarFunction(loader, ScalarFunction("geoMeasure", {TgeompointType::tgeompoint(), TemporalTypes::tfloat(), LogicalType::BOOLEAN}, MobilityDuckGeometryType(), Gen_tpoint_tfloat_to_geomeas)); RegisterSerializedScalarFunction(loader, ScalarFunction("geoMeasure", {TgeompointType::tgeompoint(), TemporalTypes::tfloat()}, MobilityDuckGeometryType(), Gen_tpoint_tfloat_to_geomeas_d)); RegisterSerializedScalarFunction(loader, ScalarFunction("geoMeasure", {TgeogpointType::tgeogpoint(), TemporalTypes::tfloat(), LogicalType::BOOLEAN}, MobilityDuckGeometryType(), Gen_tpoint_tfloat_to_geomeas)); diff --git a/src/geo/tgeompoint.cpp b/src/geo/tgeompoint.cpp index 76bfc8d2..4f50fb4e 100644 --- a/src/geo/tgeompoint.cpp +++ b/src/geo/tgeompoint.cpp @@ -140,439 +140,4 @@ void TgeompointType::RegisterScalarFunctions(ExtensionLoader &loader) { // meos_geo_transf, meos_geo_base_spatial, meos_geo_base_dist). } -/* *************************************************** - * Round-trip I/O for tgeompoint: asEWKB / asHexWKB / asHexEWKB / - * asMFJSON and the matching tgeompointFromText / FromBinary / FromEWKB / - * FromHexWKB / FromHexEWKB / FromMFJSON constructors. - * - * spaceSplit / spaceTimeSplit — set-returning splitters that bucket a - * tgeompoint trajectory into spatial (and optionally temporal) bins and - * return one row per bin, mirroring MobilityDB's - * - * RETURNS TABLE(spaceBin geometry, [timeBin timestamptz,] tpoint tgeompoint) - * - * asMVTGeom for tgeompoint - * - * asMVTGeom(tgeompoint, stbox bounds[, extent int[, buffer int[, clip bool]]]) - * RETURNS STRUCT(geom geometry, times bigint[]) - ****************************************************/ - -namespace { - -/* MEOS WKB variant flag from meos_geo.h: 0 = base, 0x04 = extended (with SRID). */ -constexpr uint8_t WKB_BASE = 0x00; -/* WKB_EXTENDED is provided by meos_geo.h as #define WKB_EXTENDED 0x04 */ - -inline Temporal *BlobToTempMVT(string_t b) { - size_t sz = b.GetSize(); - uint8_t *copy = (uint8_t *)malloc(sz); - memcpy(copy, b.GetData(), sz); - return reinterpret_cast(copy); -} - -inline STBox *BlobToStboxMVT(string_t b) { - size_t sz = b.GetSize(); - uint8_t *copy = (uint8_t *)malloc(sz); - memcpy(copy, b.GetData(), sz); - return reinterpret_cast(copy); -} - -void TgeoAsMVTGeomExec(DataChunk &args, ExpressionState &state, Vector &result) { - const idx_t row_count = args.size(); - for (idx_t i = 0; i < args.ColumnCount(); i++) args.data[i].Flatten(row_count); - const idx_t cc = args.ColumnCount(); - - auto in_temp = FlatVector::GetData(args.data[0]); - auto in_bounds = FlatVector::GetData(args.data[1]); - auto &v0 = FlatVector::Validity(args.data[0]); - auto &v1 = FlatVector::Validity(args.data[1]); - auto &out_validity = FlatVector::Validity(result); - - auto &struct_children = StructVector::GetEntries(result); - auto &geom_col = *struct_children[0]; - auto ×_col = *struct_children[1]; - auto times_entries = FlatVector::GetData(times_col); - auto ×_child = ListVector::GetEntry(times_col); - - idx_t total_times = 0; - for (idx_t row = 0; row < row_count; row++) { - if (!v0.RowIsValid(row) || !v1.RowIsValid(row)) { - out_validity.SetInvalid(row); - times_entries[row] = list_entry_t{total_times, 0}; - continue; - } - Temporal *t = BlobToTempMVT(in_temp[row]); - STBox *bx = BlobToStboxMVT(in_bounds[row]); - int32_t extent = 4096; - int32_t buffer = 256; - bool clip = true; - if (cc > 2) extent = FlatVector::GetData(args.data[2])[row]; - if (cc > 3) buffer = FlatVector::GetData(args.data[3])[row]; - if (cc > 4) clip = FlatVector::GetData(args.data[4])[row]; - - GSERIALIZED *geom = nullptr; - int64 *times = nullptr; - int count = 0; - bool found = tpoint_as_mvtgeom(t, bx, extent, buffer, clip, &geom, ×, &count); - free(t); free(bx); - if (!found || !geom) { - out_validity.SetInvalid(row); - times_entries[row] = list_entry_t{total_times, 0}; - if (geom) free(geom); - if (times) free(times); - continue; - } - /* Encode geom into the geometry struct child */ - ArenaAllocator arena(BufferAllocator::Get(state.GetContext())); - string_t enc = GSerializedToGeometry(geom, arena, geom_col); - FlatVector::GetData(geom_col)[row] = - StringVector::AddStringOrBlob(geom_col, enc); - free(geom); - /* Encode times[] into the bigint[] struct child */ - if (count > 0 && times) { - ListVector::Reserve(times_col, total_times + count); - ListVector::SetListSize(times_col, total_times + count); - times_entries[row] = list_entry_t{total_times, static_cast(count)}; - auto times_data = FlatVector::GetData(times_child); - for (int k = 0; k < count; k++) { - times_data[total_times + k] = (int64_t) times[k]; - } - total_times += count; - } else { - times_entries[row] = list_entry_t{total_times, 0}; - } - if (times) free(times); - } - if (row_count == 1) result.SetVectorType(VectorType::CONSTANT_VECTOR); -} - -} // anonymous namespace for round-trip WKB - -namespace { - -/* spaceSplit / spaceTimeSplit accept both literal and LATERAL column - * inputs through DuckDB's in_out_function plumbing. The bind callback - * only declares the return types; the per-row parameters are read at - * exec time from the input DataChunk. The local state carries the - * iteration progress so that the output is produced lazily, bounded by - * STANDARD_VECTOR_SIZE. The pattern mirrors - * duckdb/extension/icu/icu-table-range.cpp. */ - -struct SpaceSplitBindData : public TableFunctionData { - bool with_time = false; -}; - -struct SpaceSplitLocalState : public LocalTableFunctionState { - /* Row of the input chunk under split, and whether its bins have - * already been computed into the vectors below. - * space_ewkb[i] is the raw EWKB serialisation of the i-th spatial bin - * (GSERIALIZED -> EWKB when the row is loaded, decoded into the result - * vector's geometry format when emitted, using DuckDB-spatial's - * wkb_reader). tpoint holds pre-built tgeompoint-aliased BLOB values. - * time_bin is populated only by the spaceTimeSplit overload. */ - idx_t current_input_row = 0; - bool initialized_row = false; - idx_t out_idx = 0; - std::vector> space_ewkb; - std::vector time_bin; - std::vector tpoint; - - void Reset() { - space_ewkb.clear(); - time_bin.clear(); - tpoint.clear(); - out_idx = 0; - } -}; - -GSERIALIZED *DefaultOriginSplit() { - return geompoint_make3dz(0, 0.0, 0.0, 0.0); -} - -unique_ptr SpaceSplitBindCommon(ClientContext &context, - TableFunctionBindInput &input, - vector &return_types, - vector &names, - bool with_time) { - auto bd = make_uniq(); - bd->with_time = with_time; - if (with_time) { - return_types = {MobilityDuckGeometryType(), LogicalType::TIMESTAMP_TZ, TgeompointType::tgeompoint()}; - names = {"spaceBin", "timeBin", "tpoint"}; - } else { - return_types = {MobilityDuckGeometryType(), TgeompointType::tgeompoint()}; - names = {"spaceBin", "tpoint"}; - } - return std::move(bd); -} - -unique_ptr SpaceSplitBind(ClientContext &context, TableFunctionBindInput &input, - vector &return_types, vector &names) { - return SpaceSplitBindCommon(context, input, return_types, names, /*with_time=*/false); -} - -unique_ptr SpaceTimeSplitBind(ClientContext &context, TableFunctionBindInput &input, - vector &return_types, vector &names) { - return SpaceSplitBindCommon(context, input, return_types, names, /*with_time=*/true); -} - -unique_ptr SpaceSplitLocalInit(ExecutionContext &context, - TableFunctionInitInput &input, - GlobalTableFunctionState *) { - return make_uniq(); -} - -void EmitSpaceBinAt(ClientContext &context, Vector &col, idx_t row, - const std::vector &ewkb) { - if (ewkb.empty()) { - FlatVector::SetNull(col, row, true); - return; - } - GSERIALIZED *gs = geo_from_ewkb(ewkb.data(), ewkb.size(), 0); - if (!gs) { - FlatVector::SetNull(col, row, true); - return; - } - ArenaAllocator arena(BufferAllocator::Get(context)); - string_t enc = GSerializedToGeometry(gs, arena, col); - auto out_data = FlatVector::GetData(col); - out_data[row] = StringVector::AddStringOrBlob(col, enc); - free(gs); -} - -/* Read one input row's parameters and pre-compute all of its split bins - * into the local state. Called once per input row by the in_out_function - * below. - * - * Input column layout: - * spaceSplit: [0]=tgeompoint, [1]=xsize, [2]=ysize, [3]=zsize, - * [4]=sorigin (geometry, optional), - * [5]=bitmatrix (bool, optional) - * spaceTimeSplit: [0]=tgeompoint, [1]=xsize, [2]=ysize, [3]=zsize, - * [4]=duration (interval), - * [5]=sorigin (geometry, optional), - * [6]=torigin (timestamptz, optional), - * [7]=bitmatrix (bool, optional) - */ -void LoadSpaceSplitRow(ClientContext &context, SpaceSplitLocalState &state, - DataChunk &input, idx_t row_idx, bool with_time) { - state.Reset(); - for (idx_t c = 0; c < input.ColumnCount(); c++) { - input.data[c].Flatten(input.size()); - } - if (FlatVector::IsNull(input.data[0], row_idx)) { - return; - } - string_t blob = FlatVector::GetData(input.data[0])[row_idx]; - double xsize = FlatVector::GetData(input.data[1])[row_idx]; - double ysize = FlatVector::GetData(input.data[2])[row_idx]; - double zsize = FlatVector::GetData(input.data[3])[row_idx]; - - idx_t col = 4; - MeosInterval mi{}; - if (with_time) { - if (input.ColumnCount() <= col || FlatVector::IsNull(input.data[col], row_idx)) { - return; - } - mi = IntervaltToInterval(FlatVector::GetData(input.data[col])[row_idx]); - col++; - } - GSERIALIZED *origin = nullptr; - if (input.ColumnCount() > col && !FlatVector::IsNull(input.data[col], row_idx)) { - string_t origin_blob = FlatVector::GetData(input.data[col])[row_idx]; - origin = GeometryToGSerialized(origin_blob, 0); - } - col++; - TimestampTz torigin = DEFAULT_TIME_ORIGIN_MEOS; - if (with_time && input.ColumnCount() > col && !FlatVector::IsNull(input.data[col], row_idx)) { - timestamp_tz_t t = FlatVector::GetData(input.data[col])[row_idx]; - torigin = (TimestampTz) DuckDBToMeosTimestamp(t).value; - col++; - } - bool bitmatrix = true; - if (input.ColumnCount() > col && !FlatVector::IsNull(input.data[col], row_idx)) { - bitmatrix = FlatVector::GetData(input.data[col])[row_idx]; - } - if (!origin) origin = DefaultOriginSplit(); - - Temporal *temp = (Temporal *) malloc(blob.GetSize()); - memcpy(temp, blob.GetData(), blob.GetSize()); - - int count = 0; - Temporal **trajs = nullptr; - GSERIALIZED **bins = nullptr; - TimestampTz *tbins = nullptr; - if (with_time) { - trajs = tgeo_space_time_split(temp, xsize, ysize, zsize, &mi, origin, torigin, - bitmatrix, true, &bins, &tbins, &count); - } else { - trajs = tgeo_space_split(temp, xsize, ysize, zsize, origin, bitmatrix, true, &bins, - &count); - } - free(temp); - free(origin); - - if (!trajs || count <= 0) { - if (trajs) free(trajs); - if (bins) free(bins); - if (tbins) free(tbins); - return; - } - - state.space_ewkb.reserve(count); - if (with_time) state.time_bin.reserve(count); - state.tpoint.reserve(count); - - for (int i = 0; i < count; i++) { - /* Capture the spaceBin as EWKB; the DuckDB-spatial encoding happens - * when the row is emitted, where an arena allocator scoped to the - * result vector is available. */ - size_t wkb_sz = 0; - uint8_t *wkb = geo_as_ewkb(bins[i], nullptr, &wkb_sz); - if (wkb) { - state.space_ewkb.emplace_back(wkb, wkb + wkb_sz); - free(wkb); - } else { - state.space_ewkb.emplace_back(); - } - free(bins[i]); - - if (with_time) { - timestamp_tz_t t = MeosToDuckDBTimestamp(timestamp_tz_t((int64_t) tbins[i])); - state.time_bin.emplace_back(Value::TIMESTAMPTZ(t)); - } - - size_t sz = temporal_mem_size(trajs[i]); - Value tblob = Value::BLOB(reinterpret_cast(trajs[i]), sz); - tblob.Reinterpret(TgeompointType::tgeompoint()); - state.tpoint.push_back(std::move(tblob)); - free(trajs[i]); - } - free(trajs); - free(bins); - if (tbins) free(tbins); -} - -OperatorResultType SpaceSplitInOutCommon(ExecutionContext &context, TableFunctionInput &data_p, - DataChunk &input, DataChunk &output, bool with_time) { - auto &state = data_p.local_state->Cast(); - idx_t out_row = 0; - - /* PhysicalTableScan resets `output` (chunk.size() = 0) before each call - * and treats output.size() == 0 as FINISHED regardless of the returned - * OperatorResultType, while PhysicalTableInOutFunction (the LATERAL - * path) honours the return value. As in - * duckdb/extension/icu/icu-table-range.cpp, leaving the chunk untouched - * (size 0) and returning NEED_MORE_INPUT once the input chunk is drained - * stops the source-scan path and advances the LATERAL path to the next - * input chunk. */ - while (out_row < STANDARD_VECTOR_SIZE) { - if (!state.initialized_row) { - if (state.current_input_row >= input.size()) { - /* Chunk drained. Rows emitted in this call are returned as - * HAVE_MORE_OUTPUT with state.current_input_row left at - * input.size(), so the next invocation falls straight back - * into this branch with out_row == 0. */ - if (out_row > 0) { - output.SetCardinality(out_row); - return OperatorResultType::HAVE_MORE_OUTPUT; - } - state.current_input_row = 0; - return OperatorResultType::NEED_MORE_INPUT; - } - LoadSpaceSplitRow(context.client, state, input, state.current_input_row, with_time); - state.initialized_row = true; - } - if (state.out_idx >= state.tpoint.size()) { - state.current_input_row++; - state.initialized_row = false; - continue; - } - EmitSpaceBinAt(context.client, output.data[0], out_row, state.space_ewkb[state.out_idx]); - if (with_time) { - output.data[1].SetValue(out_row, state.time_bin[state.out_idx]); - output.data[2].SetValue(out_row, state.tpoint[state.out_idx]); - } else { - output.data[1].SetValue(out_row, state.tpoint[state.out_idx]); - } - state.out_idx++; - out_row++; - } - output.SetCardinality(out_row); - return OperatorResultType::HAVE_MORE_OUTPUT; -} - -OperatorResultType SpaceSplitInOut(ExecutionContext &context, TableFunctionInput &data_p, - DataChunk &input, DataChunk &output) { - return SpaceSplitInOutCommon(context, data_p, input, output, /*with_time=*/false); -} - -OperatorResultType SpaceTimeSplitInOut(ExecutionContext &context, TableFunctionInput &data_p, - DataChunk &input, DataChunk &output) { - return SpaceSplitInOutCommon(context, data_p, input, output, /*with_time=*/true); -} - -} // namespace - -void TgeompointType::RegisterTpointSplit(ExtensionLoader &loader) { - const auto T = tgeompoint(); - const auto D = LogicalType::DOUBLE; - const auto I = LogicalType::INTERVAL; - const auto TS = LogicalType::TIMESTAMP_TZ; - const auto G = MobilityDuckGeometryType(); - const auto B = LogicalType::BOOLEAN; - - /* spaceSplit overloads (tgeompoint, xsize, ysize, zsize[, sorigin geom[, bitmatrix bool]]) */ - { - std::vector> arg_lists = { - {T, D, D, D}, - {T, D, D, D, G}, - {T, D, D, D, G, B}, - }; - for (auto &args : arg_lists) { - TableFunction fn("spaceSplit", args, /*function=*/nullptr, SpaceSplitBind, - /*init_global=*/nullptr, SpaceSplitLocalInit); - fn.in_out_function = SpaceSplitInOut; - RegisterMeosFunction(loader, fn); - } - } - - /* spaceTimeSplit overloads (tgeompoint, xsize, ysize, zsize, duration[, sorigin[, torigin[, bitmatrix]]]) */ - { - std::vector> arg_lists = { - {T, D, D, D, I}, - {T, D, D, D, I, G}, - {T, D, D, D, I, G, TS}, - {T, D, D, D, I, G, TS, B}, - }; - for (auto &args : arg_lists) { - TableFunction fn("spaceTimeSplit", args, /*function=*/nullptr, SpaceTimeSplitBind, - /*init_global=*/nullptr, SpaceSplitLocalInit); - fn.in_out_function = SpaceTimeSplitInOut; - RegisterMeosFunction(loader, fn); - } - } -} - -void TgeompointType::RegisterAnalyticsViz(ExtensionLoader &loader) { - const auto T = tgeompoint(); - const auto B = StboxType::stbox(); - const auto G = MobilityDuckGeometryType(); - const auto I = LogicalType::INTEGER; - const auto BL = LogicalType::BOOLEAN; - - /* asMVTGeom returns STRUCT(geom GEOMETRY, times BIGINT[]) */ - const auto MVT_OUT = LogicalType::STRUCT({ - {"geom", G}, - {"times", LogicalType::LIST(LogicalType::BIGINT)}, - }); - duckdb::RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {T, B}, MVT_OUT, TgeoAsMVTGeomExec)); - duckdb::RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {T, B, I}, MVT_OUT, TgeoAsMVTGeomExec)); - duckdb::RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {T, B, I, I}, MVT_OUT, TgeoAsMVTGeomExec)); - duckdb::RegisterSerializedScalarFunction(loader, ScalarFunction("asMVTGeom", {T, B, I, I, BL}, MVT_OUT, TgeoAsMVTGeomExec)); - - // geoMeasure(tgeompoint | tgeogpoint, tfloat[, boolean]) is generated from the catalog - // (tpoint_tfloat_to_geomeas, meos_geo_conversion). -} - } // namespace duckdb diff --git a/src/include/geo/tgeompoint.hpp b/src/include/geo/tgeompoint.hpp index e03cb285..8a6f373c 100644 --- a/src/include/geo/tgeompoint.hpp +++ b/src/include/geo/tgeompoint.hpp @@ -18,8 +18,6 @@ struct TgeompointType { static void RegisterType(ExtensionLoader &loader); static void RegisterCastFunctions(ExtensionLoader &loader); static void RegisterScalarFunctions(ExtensionLoader &loader); - static void RegisterTpointSplit(ExtensionLoader &loader); - static void RegisterAnalyticsViz(ExtensionLoader &loader); }; } // namespace duckdb diff --git a/src/include/temporal/temporal.hpp b/src/include/temporal/temporal.hpp index a19ea0c5..21fe6776 100644 --- a/src/include/temporal/temporal.hpp +++ b/src/include/temporal/temporal.hpp @@ -28,8 +28,6 @@ struct TemporalTypes { static void RegisterTypes(ExtensionLoader &loader); static void RegisterCastFunctions(ExtensionLoader &loader); static void RegisterScalarFunctions(ExtensionLoader &loader); - static void RegisterTemporalTileSplit(ExtensionLoader &loader); - static void RegisterTnumberValueSplit(ExtensionLoader &loader); }; } // namespace duckdb diff --git a/src/mobilityduck_extension.cpp b/src/mobilityduck_extension.cpp index 32618226..04bb31b9 100644 --- a/src/mobilityduck_extension.cpp +++ b/src/mobilityduck_extension.cpp @@ -365,8 +365,6 @@ static void LoadInternal(ExtensionLoader &loader) { TemporalTypes::RegisterTypes(loader); TemporalTypes::RegisterCastFunctions(loader); TemporalTypes::RegisterScalarFunctions(loader); - TemporalTypes::RegisterTemporalTileSplit(loader); - TemporalTypes::RegisterTnumberValueSplit(loader); TboxType::RegisterType(loader); TboxType::RegisterCastFunctions(loader); @@ -382,8 +380,6 @@ static void LoadInternal(ExtensionLoader &loader) { TgeompointType::RegisterType(loader); TgeompointType::RegisterCastFunctions(loader); TgeompointType::RegisterScalarFunctions(loader); - TgeompointType::RegisterTpointSplit(loader); - TgeompointType::RegisterAnalyticsViz(loader); TgeogpointType::RegisterType(loader); TgeogpointType::RegisterCastFunctions(loader); diff --git a/src/temporal/temporal.cpp b/src/temporal/temporal.cpp index 30bc6e91..7ef7d77e 100644 --- a/src/temporal/temporal.cpp +++ b/src/temporal/temporal.cpp @@ -223,286 +223,4 @@ void TemporalTypes::RegisterScalarFunctions(ExtensionLoader &loader) { // Portable-SQL alias (MobilityDB name): ttext_cat } -// ============================================================ -// timeSplit / valueSplit / valueTimeSplit — table-function impls -// ============================================================ - -namespace { - -// ---------- timeSplit / valueSplit / valueTimeSplit ---------- -// -// Each takes its temporal value from a literal or from a LATERAL column -// through DuckDB's in_out_function, as spaceSplit and spaceTimeSplit do -// (src/geo/tgeompoint.cpp). The bind declares the result columns from the -// function_info of the registration, which states the temporal type, the bins -// the split produces and whether its value bins are integers; each input row -// is split when the output reaches it, and its bins are emitted at most -// STANDARD_VECTOR_SIZE at a time. - -struct TemporalSplitInfo : public TableFunctionInfo { - TemporalSplitInfo(LogicalType ttype_p, bool with_value_p, bool is_int_p, bool with_time_p) - : ttype(std::move(ttype_p)), with_value(with_value_p), is_int(is_int_p), - with_time(with_time_p) { - } - LogicalType ttype; // the temporal type of the input and of each piece - bool with_value; // valueSplit / valueTimeSplit: a value bin - bool is_int; // integer value bin size and origin, else double - bool with_time; // timeSplit / valueTimeSplit: a time bin -}; - -struct TemporalSplitBindData : public TableFunctionData { - TemporalSplitBindData(LogicalType ttype_p, bool with_value_p, bool is_int_p, bool with_time_p) - : ttype(std::move(ttype_p)), with_value(with_value_p), is_int(is_int_p), - with_time(with_time_p) { - } - LogicalType ttype; - bool with_value; - bool is_int; - bool with_time; -}; - -struct TemporalSplitLocalState : public LocalTableFunctionState { - idx_t current_input_row = 0; - bool initialized_row = false; - idx_t out_idx = 0; - vector value_bins; // valueSplit / valueTimeSplit - vector time_bins; // timeSplit / valueTimeSplit - vector temporals; - - void Reset() { - value_bins.clear(); - time_bins.clear(); - temporals.clear(); - out_idx = 0; - } -}; - -unique_ptr TemporalSplitBind(ClientContext &, TableFunctionBindInput &input, - vector &return_types, vector &names) { - auto &info = input.info->Cast(); - if (!info.with_value) { - return_types = {LogicalType::TIMESTAMP_TZ, info.ttype}; - names = {"time", StringUtil::Lower(info.ttype.GetAlias())}; - } else if (info.with_time) { - return_types = {info.is_int ? LogicalType::INTEGER : LogicalType::DOUBLE, - LogicalType::TIMESTAMP_TZ, info.ttype}; - names = {"value", "time", StringUtil::Lower(info.ttype.GetAlias())}; - } else { - return_types = {info.is_int ? LogicalType::BIGINT : LogicalType::DOUBLE, info.ttype}; - names = {"number", "tnumber"}; - } - return make_uniq(info.ttype, info.with_value, info.is_int, info.with_time); -} - -unique_ptr TemporalSplitLocalInit(ExecutionContext &context, TableFunctionInitInput &, - GlobalTableFunctionState *) { - EnsureMeosThreadInitialized(context.client); - return make_uniq(); -} - -/* Split one input row into the local state. Input column layout: - * timeSplit: [0]=temporal, [1]=duration, [2]=origin (optional), [3]=borderInc (optional) - * valueSplit: [0]=tnumber, [1]=size, [2]=origin (optional), [3]=borderInc (optional) - * valueTimeSplit: [0]=tnumber, [1]=vsize, [2]=duration, - * [3]=vorigin and [4]=torigin (optional, together), [5]=borderInc (optional) - * A NULL temporal, size, duration or borderInc splits into no row; an absent borderInc is true. */ -void LoadTemporalSplitRow(TemporalSplitLocalState &state, const TemporalSplitBindData &bd, - DataChunk &input, idx_t row) { - state.Reset(); - for (idx_t c = 0; c < input.ColumnCount(); c++) { - input.data[c].Flatten(input.size()); - } - if (FlatVector::IsNull(input.data[0], row) || FlatVector::IsNull(input.data[1], row)) { - return; - } - if (bd.with_value && bd.with_time && FlatVector::IsNull(input.data[2], row)) { - return; - } - const idx_t duration_col = bd.with_value ? 2 : 1; - const idx_t vorigin_col = bd.with_time ? 3 : 2; - const idx_t torigin_col = bd.with_value ? 4 : 2; - const bool has_vorigin = bd.with_value && input.ColumnCount() > vorigin_col && - !FlatVector::IsNull(input.data[vorigin_col], row); - const idx_t border_col = (bd.with_value && bd.with_time) ? 5 : 3; - bool border_inc = true; - if (input.ColumnCount() > border_col) { - if (FlatVector::IsNull(input.data[border_col], row)) { - return; - } - border_inc = FlatVector::GetData(input.data[border_col])[row]; - } - MeosInterval mi {}; - TimestampTz torigin = DEFAULT_TIME_ORIGIN_MEOS; - if (bd.with_time) { - mi = IntervaltToInterval(FlatVector::GetData(input.data[duration_col])[row]); - if (input.ColumnCount() > torigin_col && !FlatVector::IsNull(input.data[torigin_col], row)) { - timestamp_tz_t t = FlatVector::GetData(input.data[torigin_col])[row]; - torigin = static_cast(DuckDBToMeosTimestamp(t).value); - } - } - - string_t blob = FlatVector::GetData(input.data[0])[row]; - Temporal *temp = static_cast(malloc(blob.GetSize())); - memcpy(temp, blob.GetData(), blob.GetSize()); - - int count = 0; - Temporal **parts = nullptr; - TimestampTz *tbins = nullptr; - int *ibins = nullptr; - double *dbins = nullptr; - if (!bd.with_value) { - parts = temporal_time_split(temp, &mi, torigin, border_inc, &tbins, &count); - } else if (bd.is_int) { - int vsize = FlatVector::GetData(input.data[1])[row]; - int vorigin = has_vorigin ? FlatVector::GetData(input.data[vorigin_col])[row] : 0; - parts = bd.with_time - ? tint_value_time_split(temp, vsize, &mi, vorigin, torigin, border_inc, &ibins, &tbins, &count) - : tint_value_split(temp, vsize, vorigin, border_inc, &ibins, &count); - } else { - double vsize = FlatVector::GetData(input.data[1])[row]; - double vorigin = has_vorigin ? FlatVector::GetData(input.data[vorigin_col])[row] : 0.0; - parts = bd.with_time - ? tfloat_value_time_split(temp, vsize, &mi, vorigin, torigin, border_inc, &dbins, &tbins, &count) - : tfloat_value_split(temp, vsize, vorigin, border_inc, &dbins, &count); - } - free(temp); - - if (parts && count > 0) { - state.temporals.reserve(count); - if (bd.with_value) { - state.value_bins.reserve(count); - } - if (bd.with_time) { - state.time_bins.reserve(count); - } - for (int i = 0; i < count; i++) { - if (bd.with_value && bd.is_int) { - state.value_bins.push_back(bd.with_time ? Value::INTEGER(ibins[i]) : Value::BIGINT(ibins[i])); - } else if (bd.with_value) { - state.value_bins.push_back(Value::DOUBLE(dbins[i])); - } - if (bd.with_time) { - timestamp_tz_t ts = MeosToDuckDBTimestamp(timestamp_tz_t(static_cast(tbins[i]))); - state.time_bins.push_back(Value::TIMESTAMPTZ(ts)); - } - Value tblob = Value::BLOB(const_data_ptr_cast(parts[i]), temporal_mem_size(parts[i])); - tblob.Reinterpret(bd.ttype); - state.temporals.push_back(std::move(tblob)); - free(parts[i]); - } - } - free(parts); - free(ibins); - free(dbins); - free(tbins); -} - -OperatorResultType TemporalSplitInOut(ExecutionContext &, TableFunctionInput &data_p, DataChunk &input, - DataChunk &output) { - auto &bd = data_p.bind_data->Cast(); - auto &state = data_p.local_state->Cast(); - idx_t out_row = 0; - - /* As in SpaceSplitInOutCommon: on a drained input chunk the call returns - * the rows it emitted as HAVE_MORE_OUTPUT, or NEED_MORE_INPUT when it - * emitted none, so the source-scan path stops and the LATERAL path - * advances to the next chunk. */ - while (out_row < STANDARD_VECTOR_SIZE) { - if (!state.initialized_row) { - if (state.current_input_row >= input.size()) { - if (out_row > 0) { - output.SetCardinality(out_row); - return OperatorResultType::HAVE_MORE_OUTPUT; - } - state.current_input_row = 0; - return OperatorResultType::NEED_MORE_INPUT; - } - LoadTemporalSplitRow(state, bd, input, state.current_input_row); - state.initialized_row = true; - } - if (state.out_idx >= state.temporals.size()) { - state.current_input_row++; - state.initialized_row = false; - continue; - } - idx_t col = 0; - if (bd.with_value) { - output.data[col++].SetValue(out_row, state.value_bins[state.out_idx]); - } - if (bd.with_time) { - output.data[col++].SetValue(out_row, state.time_bins[state.out_idx]); - } - output.data[col].SetValue(out_row, state.temporals[state.out_idx]); - state.out_idx++; - out_row++; - } - output.SetCardinality(out_row); - return OperatorResultType::HAVE_MORE_OUTPUT; -} - -void RegisterTemporalSplit(ExtensionLoader &loader, const string &name, vector args, - LogicalType ttype, bool with_value, bool is_int, bool with_time) { - TableFunction fn(name, std::move(args), /*function=*/nullptr, TemporalSplitBind, - /*init_global=*/nullptr, TemporalSplitLocalInit); - fn.in_out_function = TemporalSplitInOut; - fn.function_info = make_shared_ptr(std::move(ttype), with_value, is_int, with_time); - RegisterMeosFunction(loader, fn); -} - -} // anonymous namespace - -void TemporalTypes::RegisterTemporalTileSplit(ExtensionLoader &loader) { - const auto I = LogicalType::INTEGER; - const auto D = LogicalType::DOUBLE; - const auto IV = LogicalType::INTERVAL; - const auto TS = LogicalType::TIMESTAMP_TZ; - const auto B = LogicalType::BOOLEAN; - - // timeSplit(temporal, interval [, timestamptz [, borderInc]]) - for (const auto &ttype : AllTypes()) { - RegisterTemporalSplit(loader, "timeSplit", {ttype, IV}, ttype, false, false, true); - RegisterTemporalSplit(loader, "timeSplit", {ttype, IV, TS}, ttype, false, false, true); - RegisterTemporalSplit(loader, "timeSplit", {ttype, IV, TS, B}, ttype, false, false, true); - } - // also for tgeompoint - for (const auto &ttype : {TgeompointType::tgeompoint()}) { - RegisterTemporalSplit(loader, "timeSplit", {ttype, IV}, ttype, false, false, true); - RegisterTemporalSplit(loader, "timeSplit", {ttype, IV, TS}, ttype, false, false, true); - RegisterTemporalSplit(loader, "timeSplit", {ttype, IV, TS, B}, ttype, false, false, true); - } - - // valueSplit is registered separately via RegisterTnumberValueSplit - - // valueTimeSplit(tint, integer, interval [, integer, timestamptz]) - RegisterTemporalSplit(loader, "valueTimeSplit", {tint(), I, IV}, tint(), true, true, true); - RegisterTemporalSplit(loader, "valueTimeSplit", {tint(), I, IV, I, TS}, tint(), true, true, true); - // valueTimeSplit(tfloat, double, interval [, double, timestamptz]) - RegisterTemporalSplit(loader, "valueTimeSplit", {tfloat(), D, IV}, tfloat(), true, false, true); - RegisterTemporalSplit(loader, "valueTimeSplit", {tfloat(), D, IV, D, TS}, tfloat(), true, false, true); - // each full form also takes borderInc - RegisterTemporalSplit(loader, "valueTimeSplit", {tint(), I, IV, I, TS, B}, tint(), true, true, true); - RegisterTemporalSplit(loader, "valueTimeSplit", {tfloat(), D, IV, D, TS, B}, tfloat(), true, false, true); -} - -/* *************************************************** - * valueSplit(tint|tfloat, size [, origin]) → SETOF (number, tnumber) - * --------------------------------------------------- - * Wraps MEOS tint_value_split / tfloat_value_split through the in_out - * function valueTimeSplit shares. Each row is a (bin-start value, - * sub-temporal) pair where the sub-temporal is the slice of the input whose - * value fell into that bin. - ****************************************************/ - -void TemporalTypes::RegisterTnumberValueSplit(ExtensionLoader &loader) { - const auto I = LogicalType::INTEGER; - const auto D = LogicalType::DOUBLE; - RegisterTemporalSplit(loader, "valueSplit", {tint(), I}, tint(), true, true, false); - RegisterTemporalSplit(loader, "valueSplit", {tint(), I, I}, tint(), true, true, false); - RegisterTemporalSplit(loader, "valueSplit", {tfloat(), D}, tfloat(), true, false, false); - RegisterTemporalSplit(loader, "valueSplit", {tfloat(), D, D}, tfloat(), true, false, false); - const auto B = LogicalType::BOOLEAN; - RegisterTemporalSplit(loader, "valueSplit", {tint(), I, I, B}, tint(), true, true, false); - RegisterTemporalSplit(loader, "valueSplit", {tfloat(), D, D, B}, tfloat(), true, false, false); -} - } // namespace duckdb diff --git a/test/sql/parity/025_temporal_tile_split.test b/test/sql/parity/025_temporal_tile_split.test index 8a61184a..650f2a13 100644 --- a/test/sql/parity/025_temporal_tile_split.test +++ b/test/sql/parity/025_temporal_tile_split.test @@ -7,6 +7,11 @@ require mobilityduck +# The bins of UTC-midnight data under the default origin, which MobilityDB reads in the session +# time zone +statement ok +SET TimeZone='UTC' + # valueSplit on tint with size 2 -> bins 0 and 4 query I @@ -98,13 +103,13 @@ SELECT count(*) FROM valueTimeSplit(tint '[1@2000-01-01 00:00:00+00, 5@2000-01-0 3 query III -SELECT value, time, tempSubtype(tint) FROM +SELECT number, time, tempSubtype(tnumber) FROM valueTimeSplit(tint '[1@2000-01-01 00:00:00+00, 5@2000-01-05 00:00:00+00]', 2, INTERVAL '2 days') - ORDER BY value, time; + ORDER BY number, time; ---- -0 2000-01-01 01:00:00+01 SequenceSet -0 2000-01-03 01:00:00+01 SequenceSet -4 2000-01-05 01:00:00+01 SequenceSet +0 2000-01-01 00:00:00+00 SequenceSet +0 2000-01-03 00:00:00+00 SequenceSet +4 2000-01-05 00:00:00+00 SequenceSet # valueSplit and valueTimeSplit take their temporal number from a column: each # row splits as its literal does (2 + 2 value bins, 3 + 2 value-time bins), and @@ -187,6 +192,6 @@ SELECT count(*) FROM tp, timeSplit(tp.temp, INTERVAL '2 days'); 5 query II -SELECT typeof(time), typeof(tint) FROM ti, timeSplit(ti.temp, INTERVAL '2 days') LIMIT 1; +SELECT typeof(s.time), typeof(s.temp) FROM ti, timeSplit(ti.temp, INTERVAL '2 days') AS s LIMIT 1; ---- TIMESTAMP WITH TIME ZONE tint diff --git a/test/sql/parity/025_temporal_tile_split_forms.test b/test/sql/parity/025_temporal_tile_split_forms.test new file mode 100644 index 00000000..b188dff1 --- /dev/null +++ b/test/sql/parity/025_temporal_tile_split_forms.test @@ -0,0 +1,52 @@ +# name: test/sql/parity/025_temporal_tile_split_forms.test +# description: The splits over the temporal types and the size forms MobilityDB declares, each +# against the rows MobilityDB answers in its regression time zone +# group: [sql] + +require mobilityduck + +statement ok +SET TimeZone='America/Los_Angeles' + +# MobilityDB: SELECT valueSplit(tbigint '[1@2001-01-01, 2@2001-01-02, 1@2001-01-03]', 2); +query II +SELECT number, tnumber::VARCHAR FROM valueSplit(tbigint '[1@2001-01-01, 2@2001-01-02, 1@2001-01-03]', 2) +ORDER BY number; +---- +0 {[1@2001-01-01 00:00:00-08, 1@2001-01-02 00:00:00-08), [1@2001-01-03 00:00:00-08]} +2 {[2@2001-01-02 00:00:00-08, 2@2001-01-03 00:00:00-08)} + +# MobilityDB: SELECT valueTimeSplit(tbigint '{1@2001-01-01, 2@2001-01-02, 1@2001-01-03}', 2, '1 week'); +query III +SELECT number, "time", tnumber::VARCHAR +FROM valueTimeSplit(tbigint '{1@2001-01-01, 2@2001-01-02, 1@2001-01-03}', 2, INTERVAL '1 week') +ORDER BY number; +---- +0 2001-01-01 00:00:00-08 {1@2001-01-01 00:00:00-08, 1@2001-01-03 00:00:00-08} +2 2001-01-01 00:00:00-08 {2@2001-01-02 00:00:00-08} + +# MobilityDB: SELECT timeSplit(ttext '[AAA@2001-01-01, BBB@2001-01-02, AAA@2001-01-03]', '1 week'); +query II +SELECT "time", temp::VARCHAR FROM timeSplit(ttext '[AAA@2001-01-01, BBB@2001-01-02, AAA@2001-01-03]', INTERVAL '1 week'); +---- +2001-01-01 00:00:00-08 ["AAA"@2001-01-01 00:00:00-08, "BBB"@2001-01-02 00:00:00-08, "AAA"@2001-01-03 00:00:00-08] + +# MobilityDB: spaceTimeSplit(tgeometry '{[Point(1 1)@2001-01-01, Point(2 2)@2001-01-02, Point(1 1)@2001-01-03], +# [Point(3 3)@2001-01-04, Point(3 3)@2001-01-05]}', 2.0, interval '2 days', 'Point(0.5 0.5)', '2001-01-15'), +# the one-size form +query III +SELECT ST_AsText(point), "time", asText(tgeo) +FROM spaceTimeSplit(tgeometry '{[Point(1 1)@2001-01-01, Point(2 2)@2001-01-02, Point(1 1)@2001-01-03],[Point(3 3)@2001-01-04, Point(3 3)@2001-01-05]}', + 2.0, INTERVAL '2 days', ST_GeomFromText('Point(0.5 0.5)'), TIMESTAMPTZ '2001-01-15') +ORDER BY 2, 1; +---- +POINT (0.5 0.5) 2001-01-01 00:00:00-08 {[POINT(1 1)@2001-01-01 00:00:00-08, POINT(2 2)@2001-01-02 00:00:00-08, POINT(2 2)@2001-01-03 00:00:00-08)} +POINT (0.5 0.5) 2001-01-03 00:00:00-08 {[POINT(1 1)@2001-01-03 00:00:00-08]} +POINT (2.5 2.5) 2001-01-03 00:00:00-08 {[POINT(3 3)@2001-01-04 00:00:00-08, POINT(3 3)@2001-01-05 00:00:00-08)} +POINT (2.5 2.5) 2001-01-05 00:00:00-08 {[POINT(3 3)@2001-01-05 00:00:00-08]} + +# MobilityDB's functions are STRICT: a NULL argument splits into no row +query I +SELECT count(*) FROM timeSplit(tint '[1@2001-01-01, 2@2001-01-02]', NULL::INTERVAL); +---- +0 diff --git a/test/sql/parity/058b_tpoint_split.test b/test/sql/parity/058b_tpoint_split.test index 52d3d3de..2ce3e250 100644 --- a/test/sql/parity/058b_tpoint_split.test +++ b/test/sql/parity/058b_tpoint_split.test @@ -6,6 +6,11 @@ require mobilityduck +# The bins of UTC-midnight data under the default origin, which MobilityDB reads in the session +# time zone +statement ok +SET TimeZone='UTC' + # spaceSplit: 10x10 trajectory with 5x5 cells -> 3 bins (0,0), (5,5), (10,10) query I @@ -14,9 +19,9 @@ SELECT count(*) FROM spaceSplit(tgeompoint '[POINT(0 0)@2000-01-01 00:00:00+00, 3 query II -SELECT ST_AsText(spaceBin), tempSubtype(tpoint) +SELECT ST_AsText(point), tempSubtype(tpoint) FROM spaceSplit(tgeompoint '[POINT(0 0)@2000-01-01 00:00:00+00, POINT(10 10)@2000-01-05 00:00:00+00]', 5.0, 5.0, 5.0) -ORDER BY ST_AsText(spaceBin); +ORDER BY ST_AsText(point); ---- POINT (0 0) SequenceSet POINT (10 10) SequenceSet @@ -53,4 +58,4 @@ SELECT count(*) FROM spaceTimeSplit( ST_GeomFromText('POINT(0 0)'), TIMESTAMP '2000-01-01'); ---- -5 +3 diff --git a/test/sql/parity/058c_tpoint_split_lateral.test b/test/sql/parity/058c_tpoint_split_lateral.test index 3f485656..2accbeff 100644 --- a/test/sql/parity/058c_tpoint_split_lateral.test +++ b/test/sql/parity/058c_tpoint_split_lateral.test @@ -6,6 +6,11 @@ require mobilityduck +# The bins of UTC-midnight data under the default origin, which MobilityDB reads in the session +# time zone +statement ok +SET TimeZone='UTC' + statement ok CREATE TABLE trip(id INTEGER, traj TGEOMPOINT); @@ -26,9 +31,9 @@ FROM trip, LATERAL spaceSplit(traj, 5.0, 5.0, 5.0); # Geometry and subtype of each bin via LATERAL — matches the literal-input case. query II -SELECT ST_AsText(spaceBin), tempSubtype(tpoint) +SELECT ST_AsText(point), tempSubtype(tpoint) FROM trip, LATERAL spaceSplit(traj, 5.0, 5.0, 5.0) -ORDER BY ST_AsText(spaceBin); +ORDER BY ST_AsText(point); ---- POINT (0 0) SequenceSet POINT (10 10) SequenceSet diff --git a/test/sql/parity/076_asmvtgeom_geomeasure.test b/test/sql/parity/076_asmvtgeom_geomeasure.test index 0553114a..886cfa30 100644 --- a/test/sql/parity/076_asmvtgeom_geomeasure.test +++ b/test/sql/parity/076_asmvtgeom_geomeasure.test @@ -39,6 +39,35 @@ SELECT ST_AsText((asMVTGeom(tgeompoint '[POINT(0 0)@2000-01-01, POINT(10 10)@200 ---- LINESTRING (0 100, 100 0) +# MobilityDB: asMVTGeom(tgeompoint '[Point(0 0)@2001-01-01, Point(100 100)@2001-04-10]', +# stbox 'STBOX X((40,40),(60,60))', clip := false) +query I +SELECT ST_AsText(round((asMVTGeom(tgeompoint '[Point(0 0)@2001-01-01, Point(100 100)@2001-04-10]', + stbox 'STBOX X((40,40),(60,60))', 4096, 256, false)).geom, 6)); +---- +LINESTRING (-8192 12288, 12288 -8192) + +# MobilityDB: asMVTGeom(tgeompoint '[Point(0 0 0)@2001-01-01, Point(100 100 100)@2001-04-10]', +# stbox 'STBOX X((40,40),(60,60))') +query I +SELECT ST_AsText(round((asMVTGeom(tgeompoint '[Point(0 0 0)@2001-01-01, Point(100 100 100)@2001-04-10]', + stbox 'STBOX X((40,40),(60,60))')).geom, 6)); +---- +LINESTRING Z (-256 4352 38.75, 4352 -256 61.25) + +# A value that meets nothing in the bounds answers NULL, as MobilityDB's does +query I +SELECT asMVTGeom(tgeompoint '{[Point(0 0)@2001-01-01], [Point(100 100)@2001-04-10]}', + stbox 'STBOX X((0,0),(60,60))') IS NULL; +---- +true + +statement error +SELECT asMVTGeom(tgeompoint '[Point(0 0)@2001-01-01, Point(100 100)@2001-04-10]', + stbox 'STBOX X((40,40),(60,60))', 0); +---- +Extent must be greater than 0 + # geoMeasure adds the M coordinate from the measure tfloat query I diff --git a/tools/codegen_duck_udfs.py b/tools/codegen_duck_udfs.py index c937a429..c72eafd2 100644 --- a/tools/codegen_duck_udfs.py +++ b/tools/codegen_duck_udfs.py @@ -3697,6 +3697,410 @@ def emit_box_tiles(f, tag, s, ins, bound, k): ""] return "\n".join(L) +# ── the pieces of a temporal value with the bins MEOS writes back: (bins..., piece) rows ────── +# MobilityDB declares timeSplit, valueSplit, valueTimeSplit, spaceSplit and spaceTimeSplit as SETOF +# a composite of the bins and the piece (`CREATE TYPE time_tint AS (time timestamptz, temp tint)`); +# the C function returns the pieces and hands each bin array back through an out-parameter +# (`outputArrays`), with the count. The catalog states per signature which array fills each column +# (`columns`, `from` naming the out-parameter or the return), the SQL defaults (`argDefaults`) and +# the sizes a short form binds (`boundArgs`). Each callable form is a table function in-out over +# its input rows, as the temporal value of a LATERAL call is a column: each row makes the one MEOS +# call when the output reaches it, and its rows are handed out a vector at a time, each bin and +# piece freed as it is written. The signatures that differ only in the temporal type share one +# body, which reads that type from its TableFunctionInfo. MobilityDB's functions are STRICT, so a +# NULL argument has no row. +SPLIT_REGISTERED = set() +SPLIT_BODIES = {} # split_body_key -> the name of the body emitted for it +# The C element of a bin array -> (the C++ type of its column's vector, the conversion of `x`, None +# for a by-value element stored as #shape_unnest stores one) +SPLIT_BIN = {"TimestampTz": ("timestamp_tz_t", "TakeTimestamp(x)"), "int": ("int32_t", None), + "int64_t": ("int64_t", None), "double": ("double", None)} + + +def _split_arg(p, sqlt): + """(DuckDB type, C++ type of the vector, the C expression over `a2`, freed) for an argument of a + split, `sqlt` the SQL type the signature declares for it; None otherwise.""" + b, n = base(p["canonical"]), norm(p["canonical"]) + if b == "Interval" and n.count("*") == 1: + return ("LogicalType::INTERVAL", "interval_t", "MeosIntervalArg(a2)", False) + if b == "GSERIALIZED" and n.count("*") == 1 and sqlt in ("geometry", "geography"): + return ("MobilityDuckGeometryType()", "string_t", + "GeogFromGeometry(a2)" if sqlt == "geography" else "GeometryToGSerialized(a2, 0)", True) + if b in SCALAR_ARG and "*" not in n: + dt, cpp, expr = SCALAR_ARG[b] + return (dt, cpp, expr, False) + return None + + +def _split_bin(f, oname, col): + """(DuckDB type, C element, the write of element `x` into column vector `v`, element freed) for + the column a bin array `oname` fills; None otherwise.""" + p = next((q for q in f["params"] if q["name"] == oname), None) + if p is None: + return None + n = re.sub(r"^struct\s+", "", norm(p["canonical"])) + if not n.endswith("**"): + return None + elem = n[:-2].strip() + if elem == "GSERIALIZED *" and col["type"] in ("geometry", "geography"): + return ("MobilityDuckGeometryType()", elem, + "FlatVector::GetData(v)[i] = GSerializedToGeometry(x, arena, v); free(x);", True) + dt = SQL_BASE_TO_DUCK.get(col["type"]) + if elem in SPLIT_BIN and dt: + cpp, conv = SPLIT_BIN[elem] + return (dt, elem, f"FlatVector::GetData<{cpp}>(v)[i] = {conv or '(%s) x' % cpp};", False) + return None + + +def shape_split(f): + """[(sqlSignature, inputs, bound, bins)] for a retired group's public function answering the + pieces of a temporal value with the bins it hands back through out-parameters, `bins` the + (column, marshal) of each bin column in the declared order; None otherwise.""" + if not retired(f) or f.get("api") != "public" or not f.get("sqlfn"): + return None + sh = f.get("shape") or {} + ar = sh.get("arrayReturn") or {} + if norm((ar.get("element") or {}).get("canonical") or "") != "Temporal *": + return None + lf = (ar.get("lengthFrom") or {}).get("name") + outs = [o.get("param") for o in sh.get("outputArrays") or []] + if not lf or not outs: + return None + ps = [p for p in f.get("params") or [] if p["name"] != lf and p["name"] not in outs] + if not ps or base(ps[0]["canonical"]) != "Temporal": + return None + forms = [] + for s in f.get("sqlSignatures") or []: + cols = s.get("columns") or [] + froms = [c.get("from") for c in cols] + if not s.get("retSet") or froms[-1:] != ["return"] or sorted(froms[:-1]) != sorted(outs): + return None + args = s.get("args") or [] + if not args or args[0] not in SIG_TEMPORAL_ACC or cols[-1].get("type") != args[0]: + return None + bound = s.get("boundArgs") or {} + ins = [p for p in ps if p["name"] not in bound] + if len(ins) != len(args): + return None + if any(_split_arg(p, t) is None for p, t in zip(ins[1:], args[1:])): + return None + bins = [(c, _split_bin(f, c["from"], c)) for c in cols[:-1]] + if any(m is None for _c, m in bins): + return None + forms.append((s, ins, bound, bins)) + return forms or None + + +def split_body_key(f, s, bound, bins): + """What a body of #shape_split depends on beyond the temporal type and the column names it reads + from its info: the parameters bound, the declared arguments and defaults, the bin types.""" + return (f["name"], tuple(sorted(bound.items())), tuple(s["args"][1:]), + tuple(str(a) for a in s.get("argDefaults") or []), tuple(m[0] for _c, m in bins)) + + +def emit_split(f, S, s, ins, bound, bins): + """The info, bind, local state and in-out function of the forms of a signature of #shape_split: + each reads the arguments its call passes and the SQL default of the others, and the info holds + the temporal type and the column names.""" + name = f["name"] + args = s["args"] + defs = s.get("argDefaults") or [None] * len(ins) + byname = {p["name"]: i for i, p in enumerate(ins)} + lf = f["shape"]["arrayReturn"]["lengthFrom"]["name"] + outs = [o["param"] for o in f["shape"]["outputArrays"]] + slot = {c["from"]: j for j, (c, _m) in enumerate(bins)} + geo = any(m[0] == "MobilityDuckGeometryType()" for _c, m in bins) + n = len(ins) + types = ", ".join([m[0] for _c, m in bins] + ["info.ttype"]) + L = [f"struct {S}Info : public TableFunctionInfo {{", + f" {S}Info(LogicalType t, vector n) : ttype(std::move(t)), names(std::move(n)) {{}}", + " LogicalType ttype;", + " vector names;", + "};", + f"struct {S}State : public LocalTableFunctionState {{", + " Temporal **parts = nullptr; int count = 0; int idx = 0;"] + ptr = lambda c: c + ("" if c.endswith("*") else " ") # noqa: E731 -- `GSERIALIZED **`, `int *` + L += [f" {ptr(m[1])}*b{j} = nullptr;" for j, (_c, m) in enumerate(bins)] + L += [" idx_t row = 0; bool loaded = false;", + " void Release() {", + " for (int k = idx; k < count; k++) {", + " free(parts[k]);"] + L += [f" free(b{j}[k]);" for j, (_c, m) in enumerate(bins) if m[3]] + L += [" }", + " free(parts);" + "".join(f" free(b{j});" for j in range(len(bins))), + " parts = nullptr;" + "".join(f" b{j} = nullptr;" for j in range(len(bins))) + + " count = 0; idx = 0;", + " }", + f" ~{S}State() {{ Release(); }}", + "};", + f"static unique_ptr {S}BindFn(ClientContext &, TableFunctionBindInput &input,", + " vector &types, vector &names) {", + f" auto &info = input.info->Cast<{S}Info>();", + f" types = {{{types}}};", + " names = info.names;", + " return make_uniq();", + "}", + f"static unique_ptr {S}InitFn(ExecutionContext &context, TableFunctionInitInput &,", + " GlobalTableFunctionState *) {", + " EnsureMeosThreadInitialized(context.client);", + f" return make_uniq<{S}State>();", + "}", + f"static OperatorResultType {S}InOutFn(ExecutionContext &, TableFunctionInput &data, DataChunk &input,", + " DataChunk &output) {", + f" auto &st = data.local_state->Cast<{S}State>();"] + if geo: + L.append(" ArenaAllocator arena(Allocator::DefaultAllocator());") + L += [" idx_t i = 0;", + " while (i < STANDARD_VECTOR_SIZE) {", + " if (!st.loaded) {", + " if (st.row >= input.size()) {", + " if (i > 0) {", + " output.SetCardinality(i);", + " return OperatorResultType::HAVE_MORE_OUTPUT;", + " }", + " st.row = 0;", + " return OperatorResultType::NEED_MORE_INPUT;", + " }", + " const idx_t k = input.ColumnCount();", + f" UnifiedVectorFormat u[{n}];", + f" idx_t r[{n}];", + " bool valid = true;", + " for (idx_t c = 0; c < k; c++) {", + " input.data[c].ToUnifiedFormat(input.size(), u[c]);", + " r[c] = u[c].sel->get_index(st.row);", + " valid = valid && u[c].validity.RowIsValid(r[c]);", + " }", + " if (valid) {", + " Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]);"] + call, frees = ["t"], [] + for p in [q for q in f["params"] if q["name"] != lf and q["name"] not in outs][1:]: + nm = p["name"] + if nm in bound: + call.append(str(bound[nm])) + continue + i = byname[nm] + _dt, cpp, expr, freed = _split_arg(p, args[i]) + e = expr.replace("a2", f"UnifiedVectorFormat::GetData<{cpp}>(u[{i}])[r[{i}]]") + if defs[i] is not None: + if freed: + d = '%s("%s", -1)' % ("geog_in" if args[i] == "geography" else "geom_in", + str(defs[i]).strip().strip("'")) + else: + d = forward_literal(p, defs[i]) + if d is None or base(p["canonical"]) == "Interval": + raise ValueError(f"{name}: no literal for {nm}") + e = f"(k > {i} ? {e} : {d})" + if freed: + L.append(f" GSERIALIZED *g{i} = {e};") + frees.append(f"g{i}") + call.append(f"g{i}") + else: + call.append(e) + call += [f"&st.b{slot[o]}" for o in outs] + ["&st.count"] + L += [f" st.parts = {name}({', '.join(call)});", + " free(t);" + "".join(f" free({g});" for g in frees), + " if (!st.parts) st.count = 0;", + " }", + " st.loaded = true;", + " }", + " if (st.idx >= st.count) {", + " st.Release();", + " st.loaded = false;", + " st.row++;", + " continue;", + " }"] + for j, (_c, m) in enumerate(bins): + L += [" {", + f" auto &v = output.data[{j}];", + f" {ptr(m[1])}x = st.b{j}[st.idx];", + f" {m[2]}", + " }"] + L += [" {", + f" auto &v = output.data[{len(bins)}];", + " Temporal *x = st.parts[st.idx];", + " FlatVector::GetData(v)[i] = StringVector::AddStringOrBlob(v, (const char *) x, " + "temporal_mem_size(x));", + " free(x);", + " }", + " st.idx++; i++;", + " }", + " output.SetCardinality(i);", + " return OperatorResultType::HAVE_MORE_OUTPUT;", + "}", + f"static TableFunction {S}Table(TableFunction fn, const LogicalType &t, vector names) {{", + f" fn.bind = {S}BindFn;", + f" fn.init_local = {S}InitFn;", + f" fn.in_out_function = {S}InOutFn;", + f" fn.function_info = make_shared_ptr<{S}Info>(t, std::move(names));", + " return fn;", + "}", + ""] + return "\n".join(L) + +# ── one row of values MEOS writes back: a composite answered as a STRUCT ────────────────────── +# MobilityDB declares asMVTGeom as RETURNS geom_times (`CREATE TYPE geom_times AS (geom geometry, +# times bigint[])`): tpoint_as_mvtgeom answers whether the value meets the bounds and hands the +# geometry back through one out-parameter and the times through an array and its count, which the +# catalog states per signature (`columns`, `from` naming each out-parameter, an array column typed +# `T[]` read whole). The scalar reads the arguments its call passes and the SQL default of the +# others, as #emit_split reads them, and a call that meets nothing, or a NULL argument (the function +# is STRICT), answers NULL. + + +def _row_arg(p, sqlt): + """#_split_arg, and a box or another value a blob carries (`PTR_IN`) as the declared SQL type.""" + a = _split_arg(p, sqlt) + if a is not None: + return a + b, n = base(p["canonical"]), norm(p["canonical"]) + dt = SQL_BASE_TO_DUCK.get(sqlt) + if n.count("*") == 1 and b in PTR_IN and PTR_IN[b][0] != "MD_TEMPORAL" and dt: + return (dt, "string_t", PTR_IN[b][1] % "a2", True) + return None + + +def _row_col(f, col, arrays, lenp): + """(DuckDB type, C type of the out-parameter's target, kind, element C++ type) for a column of + #shape_row_out: a geometry handed back alone, or an array of by-value elements read whole.""" + p = next((q for q in f["params"] if q["name"] == col.get("from")), None) + if p is None: + return None + n = re.sub(r"^struct\s+", "", norm(p["canonical"])) + if not n.endswith("**"): + return None + tgt = n[:-1].strip() + if p["name"] in arrays: + elem = tgt[:-1].strip() + et = col["type"][:-2] if col["type"].endswith("[]") else None + dt = SQL_BASE_TO_DUCK.get(et or "") + if not lenp or elem not in SPLIT_BIN or SPLIT_BIN[elem][1] or not dt: + return None + return (f"LogicalType::LIST({dt})", tgt, "list", SPLIT_BIN[elem][0]) + if tgt == "GSERIALIZED *" and col["type"] in ("geometry", "geography"): + return ("MobilityDuckGeometryType()", tgt, "geo", None) + return None + + +def shape_row_out(f): + """[(sqlSignature, inputs, columns)] for a retired group's public function answering one row of + values it hands back through out-parameters, with a bool stating whether there is one; None + otherwise. `columns` holds the (column, marshal) of each declared column.""" + if not retired(f) or f.get("api") != "public" or not f.get("sqlfn"): + return None + if norm(f["returnType"]["canonical"]) != "bool": + return None + sh = f.get("shape") or {} + outs = sh.get("outParams") or [] + arrays = {o.get("param") for o in sh.get("outputArrays") or []} + sigs = f.get("sqlSignatures") or [] + if not sigs or not outs: + return None + forms = [] + for s in sigs: + cols = s.get("columns") or [] + froms = [c.get("from") for c in cols] + if s.get("retSet") or not cols or not set(froms) <= set(outs) or s.get("boundArgs"): + return None + rest = [o for o in outs if o not in froms] + lenp = rest[0] if len(rest) == 1 and arrays else None + if (arrays and not lenp) or (not arrays and rest): + return None + ms = [(c, _row_col(f, c, arrays, lenp)) for c in cols] + if any(m is None for _c, m in ms): + return None + ins = [p for p in f["params"] if p["name"] not in outs] + args = s.get("args") or [] + if len(ins) != len(args) or args[0] not in SIG_TEMPORAL_ACC or base(ins[0]["canonical"]) != "Temporal": + return None + if any(_row_arg(p, a) is None for p, a in zip(ins[1:], args[1:])): + return None + forms.append((s, ins, ms)) + return forms or None + + +def emit_row_out(f, tag, s, ins, ms): + """The scalar of a signature of #shape_row_out, over every argument count its defaults allow.""" + name = f["name"] + args = s["args"] + defs = s.get("argDefaults") or [None] * len(ins) + n = len(ins) + outs = f["shape"]["outParams"] + geo = any(m[2] == "geo" for _c, m in ms) + L = [f"static void Gen_{name}_{tag}(DataChunk &args, ExpressionState &, Vector &result) {{", + " EnsureMeosThreadInitialized();", + " const idx_t rows = args.size(), k = args.ColumnCount();", + f" UnifiedVectorFormat u[{n}];", + " for (idx_t c = 0; c < k; c++) args.data[c].ToUnifiedFormat(rows, u[c]);", + " result.SetVectorType(VectorType::FLAT_VECTOR);", + " auto &cols = StructVector::GetEntries(result);", + " auto &valid_out = FlatVector::Validity(result);"] + if geo: + L.append(" ArenaAllocator arena(Allocator::DefaultAllocator());") + empty = "".join(f" FlatVector::GetData(*cols[{j}])[i] = list_entry_t{{ListVector::GetListSize(*cols[{j}]), 0}};" + for j, (_c, m) in enumerate(ms) if m[2] == "list") + L += [" for (idx_t i = 0; i < rows; i++) {", + f" idx_t r[{n}];", + " bool valid = true;", + " for (idx_t c = 0; c < k; c++) {", + " r[c] = u[c].sel->get_index(i);", + " valid = valid && u[c].validity.RowIsValid(r[c]);", + " }", + f" if (!valid) {{ valid_out.SetInvalid(i);{empty} continue; }}", + " Temporal *t = BlobToTemporal(UnifiedVectorFormat::GetData(u[0])[r[0]]);"] + call, frees = ["t"], [] + for i, p in enumerate(ins[1:], 1): + _dt, cpp, expr, freed = _row_arg(p, args[i]) + e = expr.replace("a2", f"UnifiedVectorFormat::GetData<{cpp}>(u[{i}])[r[{i}]]") + if defs[i] is not None: + d = forward_literal(p, defs[i]) + if d is None or freed: + raise ValueError(f"{name}: no literal for {p['name']}") + e = f"(k > {i} ? {e} : {d})" + if freed: + L.append(f" auto *x{i} = {e};") + frees.append(f"x{i}") + call.append(f"x{i}") + else: + call.append(e) + tgt = {c["from"]: m[1] for c, m in ms} + lenp = next((o for o in outs if o not in tgt), None) + for o in outs: + if o in tgt: + L.append(f" {tgt[o]}{'' if tgt[o].endswith('*') else ' '}o_{o} = nullptr;") + if lenp: + L.append(f" int o_{lenp} = 0;") + call += [f"&o_{o}" for o in outs] + L += [f" bool found = {name}({', '.join(call)});", + " free(t);" + "".join(f" free({x});" for x in frees), + " if (!found" + "".join(f" || !o_{c['from']}" for c, m in ms if m[2] == "geo") + ") {", + " valid_out.SetInvalid(i);" + "".join(f" free(o_{o});" for o in outs if o in tgt) + empty, + " continue;", + " }"] + for j, (c, m) in enumerate(ms): + o = c["from"] + if m[2] == "geo": + L += [" {", + f" auto &v = *cols[{j}];", + f" FlatVector::GetData(v)[i] = GSerializedToGeometry(o_{o}, arena, v);", + f" free(o_{o});", + " }"] + else: + L += [" {", + f" auto &v = *cols[{j}];", + " idx_t off = ListVector::GetListSize(v);", + f" ListVector::Reserve(v, off + o_{lenp});", + f" auto d = FlatVector::GetData<{m[3]}>(ListVector::GetEntry(v));", + f" for (int e = 0; e < o_{lenp}; e++) d[off + e] = ({m[3]}) o_{o}[e];", + f" FlatVector::GetData(v)[i] = list_entry_t{{off, (idx_t) o_{lenp}}};", + f" ListVector::SetListSize(v, off + o_{lenp});", + f" free(o_{o});", + " }"] + L += [" }", + " if (args.AllConstant()) result.SetVectorType(VectorType::CONSTANT_VECTOR);", + "}", + ""] + return "\n".join(L) + # ── the boxes of a spatial value and the tile of a point: one scalar per row ─────────────── # spaceBoxes and spaceTimeBoxes answer stbox[] from a spatial temporal value, its sizes, an origin @@ -5425,17 +5829,12 @@ def emit_container_scalar(f, ops, rev): # no longer listed here. Empty: every @sqlfn of a retired group is generated. # unnest: DuckDB's own unnest cannot be overloaded, so the temporal unnest registers under the # name the catalog gives the other engines, temporalUnnest (#shape_unnest). -# The tile and bin groups: the splits of a temporal value into its tiles (spaceSplit, timeSplit, -# valueSplit and their combinations) return arrays of temporal values that no shape takes yet; -# src/temporal/temporal.cpp keeps them. # box2d and box3d: PostGIS's box types, which DuckDB does not have, so box2d(stbox) and # box3d(stbox) answer no type this surface registers; no hand registration answers them either. # stboxX: the catalog gives stbox_make, whose eleven parameters the SQL constructor fills from # five arguments, the flags through boundArgs and the SRID read last in SQL and fourth in C; no # shape reads that mapping, and no hand registration answers stboxX either. -# asMVTGeom: its result is the composite geom_times (a geometry and the bigint[] of its times), -# which tpoint_as_mvtgeom hands back through three out-parameters; no shape builds a STRUCT from -# out-parameters, so src/geo/tgeompoint.cpp keeps it. The clusters of a geometry array +# The clusters of a geometry array # (clusterKMeans, clusterDBSCAN, clusterIntersecting, clusterWithin) answer an array, of integers # or of geometries, with its count through an out-parameter, which no shape returns from an # array of geometries; no hand registration answers them either. @@ -5452,8 +5851,6 @@ def emit_container_scalar(f, ops, rev): # tjsonbSet and tjsonbSetLax register nothing: tjsonb_set reads its keys as a text ** and a count # no marshalling fills from a text[], and tjsonbSet binds no literal for handle_null. RETIRE_UNCOVERED_OK = {"unnest", "box2d", "box3d", "stboxX", "tjsonbSet", - "spaceSplit", "spaceTimeSplit", "timeSplit", - "valueSplit", "valueTimeSplit", "asMVTGeom", "clusterKMeans", "clusterDBSCAN", "clusterIntersecting", "clusterWithin", "pointCloudSchemaRegister", "rasterFromBinary", "rasterFromHexWKB", "numBands", "upperLeftX", @@ -6949,6 +7346,54 @@ def gen_cpp(fns, out_path, declared=None, aliases=None): specific_regs.append(f' loader.RegisterFunction(TableFunction("{nm}", ' f'{{{", ".join(types_)}}}, {S_}ExecFn, {S_}BindFn, {S_}InitFn));') continue + # one row of values handed back through out-parameters (asMVTGeom): a STRUCT scalar per + # declared signature, over every argument count its defaults allow + _ro = shape_row_out(f) + if _ro: + STATE["grp"] = f.get("group") or "meos_ungrouped" + for j, (s_, ins_, ms_) in enumerate(_ro): + tag = f"row{j}" + rt_ = "LogicalType::STRUCT({%s})" % ", ".join( + '{"%s", %s}' % (c["name"], m[0]) for c, m in ms_) + acc_ = SIG_TEMPORAL_ACC[s_["args"][0]] + regs_ = [] + for k_ in box_tile_forms(s_, ins_): + types_ = tuple([acc_] + [_row_arg(p, a)[0] for p, a in zip(ins_[1:k_], s_["args"][1:k_])]) + for nm in reg_names(f, s_.get("sqlName") or f["sqlfn"], aliases): + if (reg_name(nm, f), types_) not in SPLIT_REGISTERED: + regs_.append((reg_name(nm, f), types_)) + if not regs_: + continue + bodies.append(emit_row_out(f, tag, s_, ins_, ms_)) + for nm, types_ in regs_: + SPLIT_REGISTERED.add((nm, types_)) + specific_regs.append(f' RegisterSerializedScalarFunction(loader, ScalarFunction(' + f'"{nm}", {{{", ".join(types_)}}}, {rt_}, Gen_{f["name"]}_{tag}));') + continue + # the pieces of a temporal value with their bins (timeSplit, spaceTimeSplit): a table + # function in-out per declared form, one body per form over every temporal type + _sp = shape_split(f) + if _sp: + STATE["grp"] = f.get("group") or "meos_ungrouped" + for s_, ins_, bound_, bins_ in _sp: + acc_ = SIG_TEMPORAL_ACC[s_["args"][0]] + key_ = split_body_key(f, s_, bound_, bins_) + cols_ = ", ".join('"%s"' % c["name"] for c in s_["columns"]) + for k_ in box_tile_forms(s_, ins_): + S_ = f"Split_{f['name']}_{len(SPLIT_BODIES)}" if key_ not in SPLIT_BODIES else None + types_ = [acc_] + [_split_arg(p, t)[0] for p, t in zip(ins_[1:k_], s_["args"][1:k_])] + nms = [reg_name(nm, f) for nm in reg_names(f, s_.get("sqlName") or f["sqlfn"], aliases) + if (reg_name(nm, f), tuple(types_)) not in SPLIT_REGISTERED] + if not nms: + continue + if S_: + SPLIT_BODIES[key_] = S_ + bodies.append(emit_split(f, S_, s_, ins_, bound_, bins_)) + for nm in nms: + SPLIT_REGISTERED.add((nm, tuple(types_))) + specific_regs.append(f' loader.RegisterFunction({SPLIT_BODIES[key_]}Table(TableFunction(' + f'"{nm}", {{{", ".join(types_)}}}, nullptr), {acc_}, {{{cols_}}}));') + continue # the boxes of a spatial value and the tile of a point (spaceBoxes, getSpaceTile): a scalar # per declared form over the first operand types its signatures name _bs = shape_box_scalars(f)