[Bug](branch-21) fix the compatibility cause coredump during upgrade (#52720)

### What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:
the PR https://github.com/apache/doris/pull/50310 introduce,
shouldn't change the be version in branch-21, others before
compatibility code will be error


### Release note

None

### Check List (For Author)

- Test <!-- At least one of them must be included. -->
    - [ ] Regression test
    - [ ] Unit Test
    - [ ] Manual test (add detailed scripts or steps below)
    - [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
        - [ ] Previous test can cover this change.
        - [ ] No code files have been changed.
        - [ ] Other reason <!-- Add your reason?  -->

- Behavior changed:
    - [ ] No.
    - [ ] Yes. <!-- Explain the behavior change -->

- Does this need documentation?
    - [ ] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->

### Check List (For Reviewer who merge this PR)

- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
This commit is contained in:
zhangstar333
2025-07-09 11:00:10 +08:00
committed by GitHub
parent 560097e491
commit 3c38843e0d
19 changed files with 342 additions and 170 deletions

View File

@ -35,8 +35,10 @@ import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMap
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbers;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbersOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeOuterV2;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeSplit;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeSplitOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeV2;
import org.apache.doris.nereids.trees.expressions.functions.generator.PosExplode;
import org.apache.doris.nereids.trees.expressions.functions.generator.PosExplodeOuter;
@ -55,8 +57,10 @@ import java.util.Set;
*/
public class BuiltinTableGeneratingFunctions implements FunctionHelper {
public final List<TableGeneratingFunc> tableGeneratingFunctions = ImmutableList.of(
tableGenerating(Explode.class, "explode"),
tableGenerating(ExplodeOuter.class, "explode_outer"),
tableGenerating(Explode.class, "explode_v1"),
tableGenerating(ExplodeV2.class, "explode_v2", "explode"),
tableGenerating(ExplodeOuter.class, "explode_v1_outer"),
tableGenerating(ExplodeOuterV2.class, "explode_v2_outer", "explode_outer"),
tableGenerating(ExplodeMap.class, "explode_map"),
tableGenerating(ExplodeMapOuter.class, "explode_map_outer"),
tableGenerating(ExplodeJsonObject.class, "explode_json_object"),
@ -80,7 +84,8 @@ public class BuiltinTableGeneratingFunctions implements FunctionHelper {
);
public static final ImmutableSet<String> RETURN_MULTI_COLUMNS_FUNCTIONS = new ImmutableSortedSet.Builder<String>(
String.CASE_INSENSITIVE_ORDER).add("explode").add("explode_outer").build();
String.CASE_INSENSITIVE_ORDER).add("explode_v2").add("explode_v2_outer").add("explode").add("explode_outer")
.build();
public Set<String> getReturnManyColumnFunctions() {
return RETURN_MULTI_COLUMNS_FUNCTIONS;

View File

@ -20,34 +20,31 @@ package org.apache.doris.nereids.trees.expressions.functions.generator;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
import org.apache.doris.nereids.trees.expressions.functions.SearchSignature;
import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.ArrayType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import org.apache.doris.nereids.types.StructField;
import org.apache.doris.nereids.types.StructType;
import org.apache.doris.nereids.types.coercion.AnyDataType;
import org.apache.doris.nereids.types.coercion.FollowToAnyDataType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
/**
* explode([1, 2, 3]), generate three rows include 1, 2 and 3.
* explode([1, 2, 3], [4, 5, 6]) generates two columns and three rows
* where the first column contains 1, 2, 3, and the second column contains 4, 5, 6.
* explode([1, 2, 3]), generate 3 lines include 1, 2 and 3.
*/
public class Explode extends TableGeneratingFunction implements CustomSignature, ComputePrecision, AlwaysNullable {
public class Explode extends TableGeneratingFunction implements BinaryExpression, AlwaysNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(new FollowToAnyDataType(0)).args(ArrayType.of(new AnyDataType(0)))
);
/**
* constructor with one or more argument.
* constructor with 1 argument.
*/
public Explode(Expression[] args) {
super("explode", args);
public Explode(Expression arg) {
super("explode_v1", arg);
}
/**
@ -55,43 +52,17 @@ public class Explode extends TableGeneratingFunction implements CustomSignature,
*/
@Override
public Explode withChildren(List<Expression> children) {
Preconditions.checkArgument(!children.isEmpty());
return new Explode(children.toArray(new Expression[0]));
Preconditions.checkArgument(children.size() == 1);
return new Explode(children.get(0));
}
@Override
public FunctionSignature computePrecision(FunctionSignature signature) {
return signature;
}
@Override
public FunctionSignature customSignature() {
List<DataType> arguments = new ArrayList<>();
ImmutableList.Builder<StructField> structFields = ImmutableList.builder();
for (int i = 0; i < children.size(); i++) {
if (children.get(i).getDataType().isNullType()) {
arguments.add(ArrayType.of(NullType.INSTANCE));
structFields.add(
new StructField("col" + (i + 1), NullType.INSTANCE, true, ""));
} else if (children.get(i).getDataType().isArrayType()) {
structFields.add(
new StructField("col" + (i + 1),
((ArrayType) (children.get(i)).getDataType()).getItemType(), true, ""));
arguments.add(children.get(i).getDataType());
} else {
SearchSignature.throwCanNotFoundFunctionException(this.getName(), getArguments());
}
}
return FunctionSignature.of(new StructType(structFields.build()), arguments);
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitExplode(this, context);
}
@Override
public FunctionSignature searchSignature(List<FunctionSignature> signatures) {
return super.searchSignature(signatures);
}
}

View File

@ -20,34 +20,31 @@ package org.apache.doris.nereids.trees.expressions.functions.generator;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
import org.apache.doris.nereids.trees.expressions.functions.SearchSignature;
import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.ArrayType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import org.apache.doris.nereids.types.StructField;
import org.apache.doris.nereids.types.StructType;
import org.apache.doris.nereids.types.coercion.AnyDataType;
import org.apache.doris.nereids.types.coercion.FollowToAnyDataType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
/**
* explode_outer([1, 2, 3]), generate three rows include 1, 2 and 3.
* explode_outer([1, 2, 3], [4, 5, 6]) generates two columns and three rows
* where the first column contains 1, 2, 3, and the second column contains 4, 5, 6.
* explode([1, 2, 3]), generate 3 lines include 1, 2 and 3.
*/
public class ExplodeOuter extends TableGeneratingFunction implements CustomSignature, ComputePrecision, AlwaysNullable {
public class ExplodeOuter extends TableGeneratingFunction implements BinaryExpression, AlwaysNullable {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(new FollowToAnyDataType(0)).args(ArrayType.of(new AnyDataType(0)))
);
/**
* constructor with one or more argument.
* constructor with 1 argument.
*/
public ExplodeOuter(Expression[] args) {
super("explode_outer", args);
public ExplodeOuter(Expression arg) {
super("explode_v2_outer", arg);
}
/**
@ -55,43 +52,17 @@ public class ExplodeOuter extends TableGeneratingFunction implements CustomSigna
*/
@Override
public ExplodeOuter withChildren(List<Expression> children) {
Preconditions.checkArgument(!children.isEmpty());
return new ExplodeOuter(children.toArray(new Expression[0]));
Preconditions.checkArgument(children.size() == 1);
return new ExplodeOuter(children.get(0));
}
@Override
public FunctionSignature computePrecision(FunctionSignature signature) {
return signature;
}
@Override
public FunctionSignature customSignature() {
List<DataType> arguments = new ArrayList<>();
ImmutableList.Builder<StructField> structFields = ImmutableList.builder();
for (int i = 0; i < children.size(); i++) {
if (children.get(i).getDataType().isNullType()) {
arguments.add(ArrayType.of(NullType.INSTANCE));
structFields.add(
new StructField("col" + (i + 1), NullType.INSTANCE, true, ""));
} else if (children.get(i).getDataType().isArrayType()) {
structFields.add(
new StructField("col" + (i + 1),
((ArrayType) (children.get(i)).getDataType()).getItemType(), true, ""));
arguments.add(children.get(i).getDataType());
} else {
SearchSignature.throwCanNotFoundFunctionException(this.getName(), getArguments());
}
}
return FunctionSignature.of(new StructType(structFields.build()), arguments);
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitExplodeOuter(this, context);
}
@Override
public FunctionSignature searchSignature(List<FunctionSignature> signatures) {
return super.searchSignature(signatures);
}
}

View File

@ -0,0 +1,98 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids.trees.expressions.functions.generator;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
import org.apache.doris.nereids.trees.expressions.functions.SearchSignature;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.ArrayType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import org.apache.doris.nereids.types.StructField;
import org.apache.doris.nereids.types.StructType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
/**
* explode_outer([1, 2, 3]), generate three rows include 1, 2 and 3.
* explode_outer([1, 2, 3], [4, 5, 6]) generates two columns and three rows
* where the first column contains 1, 2, 3, and the second column contains 4, 5, 6.
*/
public class ExplodeOuterV2 extends TableGeneratingFunction
implements CustomSignature, ComputePrecision, AlwaysNullable {
/**
* constructor with one or more argument.
*/
public ExplodeOuterV2(Expression[] args) {
super("explode_v2_outer", args);
}
/**
* withChildren.
*/
@Override
public ExplodeOuterV2 withChildren(List<Expression> children) {
Preconditions.checkArgument(!children.isEmpty());
return new ExplodeOuterV2(children.toArray(new Expression[0]));
}
@Override
public FunctionSignature computePrecision(FunctionSignature signature) {
return signature;
}
@Override
public FunctionSignature customSignature() {
List<DataType> arguments = new ArrayList<>();
ImmutableList.Builder<StructField> structFields = ImmutableList.builder();
for (int i = 0; i < children.size(); i++) {
if (children.get(i).getDataType().isNullType()) {
arguments.add(ArrayType.of(NullType.INSTANCE));
structFields.add(
new StructField("col" + (i + 1), NullType.INSTANCE, true, ""));
} else if (children.get(i).getDataType().isArrayType()) {
structFields.add(
new StructField("col" + (i + 1),
((ArrayType) (children.get(i)).getDataType()).getItemType(), true, ""));
arguments.add(children.get(i).getDataType());
} else {
SearchSignature.throwCanNotFoundFunctionException(this.getName(), getArguments());
}
}
return FunctionSignature.of(new StructType(structFields.build()), arguments);
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitExplodeOuterV2(this, context);
}
@Override
public FunctionSignature searchSignature(List<FunctionSignature> signatures) {
return super.searchSignature(signatures);
}
}

View File

@ -0,0 +1,97 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids.trees.expressions.functions.generator;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.ComputePrecision;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
import org.apache.doris.nereids.trees.expressions.functions.SearchSignature;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.ArrayType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import org.apache.doris.nereids.types.StructField;
import org.apache.doris.nereids.types.StructType;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
/**
* explode([1, 2, 3]), generate three rows include 1, 2 and 3.
* explode([1, 2, 3], [4, 5, 6]) generates two columns and three rows
* where the first column contains 1, 2, 3, and the second column contains 4, 5, 6.
*/
public class ExplodeV2 extends TableGeneratingFunction implements CustomSignature, ComputePrecision, AlwaysNullable {
/**
* constructor with one or more argument.
*/
public ExplodeV2(Expression[] args) {
super("explode_v2", args);
}
/**
* withChildren.
*/
@Override
public ExplodeV2 withChildren(List<Expression> children) {
Preconditions.checkArgument(!children.isEmpty());
return new ExplodeV2(children.toArray(new Expression[0]));
}
@Override
public FunctionSignature computePrecision(FunctionSignature signature) {
return signature;
}
@Override
public FunctionSignature customSignature() {
List<DataType> arguments = new ArrayList<>();
ImmutableList.Builder<StructField> structFields = ImmutableList.builder();
for (int i = 0; i < children.size(); i++) {
if (children.get(i).getDataType().isNullType()) {
arguments.add(ArrayType.of(NullType.INSTANCE));
structFields.add(
new StructField("col" + (i + 1), NullType.INSTANCE, true, ""));
} else if (children.get(i).getDataType().isArrayType()) {
structFields.add(
new StructField("col" + (i + 1),
((ArrayType) (children.get(i)).getDataType()).getItemType(), true, ""));
arguments.add(children.get(i).getDataType());
} else {
SearchSignature.throwCanNotFoundFunctionException(this.getName(), getArguments());
}
}
return FunctionSignature.of(new StructType(structFields.build()), arguments);
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitExplodeV2(this, context);
}
@Override
public FunctionSignature searchSignature(List<FunctionSignature> signatures) {
return super.searchSignature(signatures);
}
}

View File

@ -35,8 +35,10 @@ import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeMap
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbers;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeNumbersOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeOuterV2;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeSplit;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeSplitOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.ExplodeV2;
import org.apache.doris.nereids.trees.expressions.functions.generator.PosExplode;
import org.apache.doris.nereids.trees.expressions.functions.generator.PosExplodeOuter;
import org.apache.doris.nereids.trees.expressions.functions.generator.TableGeneratingFunction;
@ -55,6 +57,14 @@ public interface TableGeneratingFunctionVisitor<R, C> {
return visitTableGeneratingFunction(explodeOuter, context);
}
default R visitExplodeV2(ExplodeV2 explode, C context) {
return visitTableGeneratingFunction(explode, context);
}
default R visitExplodeOuterV2(ExplodeOuterV2 explodeOuter, C context) {
return visitTableGeneratingFunction(explodeOuter, context);
}
default R visitExplodeMap(ExplodeMap explode, C context) {
return visitTableGeneratingFunction(explode, context);
}

View File

@ -42,7 +42,8 @@ public final class FunctionAlias implements ExprRewriteRule {
.put("inet6_aton", "ipv6_string_to_num_or_null").put("lcase", "lower").put("add_months", "months_add")
.put("current_timestamp", "now").put("localtime", "now").put("localtimestamp", "now").put("nvl", "ifnull")
.put("rand", "random").put("sha", "sha1").put("substr", "substring").put("ucase", "upper")
.put("approx_count_distinct", "ndv").build();
.put("approx_count_distinct", "ndv").put("explode", "explode_v2").put("explode_outer", "explode_v2_outer")
.build();
@Override
public Expr apply(Expr expr, Analyzer analyzer, ExprRewriter.ClauseType clauseType) throws AnalysisException {

View File

@ -0,0 +1,35 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.common;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
public class ConfigTest {
@Test
public void test() {
System.out.println(Config.max_be_exec_version);
System.out.println(Config.min_be_exec_version);
System.out.println(Config.be_exec_version);
// YOU MUST NOT CHANGE THIS TEST !
// if you want to change be_exec_version, you should know what you are doing
Assertions.assertEquals(6, Config.max_be_exec_version);
Assertions.assertEquals(0, Config.min_be_exec_version);
Assertions.assertEquals(6, Config.be_exec_version);
}
}

View File

@ -43,7 +43,7 @@ public class ExplodeOuterTest {
// build explode_outer(array<int>, array<str>) expression
Expression[] args = {SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)),
SlotReference.of("str", ArrayType.of(StringType.INSTANCE))};
ExplodeOuter explode = new ExplodeOuter(args);
ExplodeOuterV2 explode = new ExplodeOuterV2(args);
// check signature
List<FunctionSignature> signatures = explode.getSignatures();
@ -65,7 +65,7 @@ public class ExplodeOuterTest {
public void testGetSignaturesWithNull() {
// build explode(null, array<int>) expression
Expression[] args = { SlotReference.of("null", NullType.INSTANCE), SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE))};
ExplodeOuter explode = new ExplodeOuter(args);
ExplodeOuterV2 explode = new ExplodeOuterV2(args);
// check signature
List<FunctionSignature> signatures = explode.getSignatures();
@ -87,7 +87,7 @@ public class ExplodeOuterTest {
public void testGetSignaturesWithInvalidArgument() {
// build explode_outer(int)
Expression[] args = { SlotReference.of("int", IntegerType.INSTANCE) };
ExplodeOuter explode = new ExplodeOuter(args);
ExplodeOuterV2 explode = new ExplodeOuterV2(args);
Assertions.assertThrows(AnalysisException.class, explode::getSignatures);
}

View File

@ -43,7 +43,7 @@ public class ExplodeTest {
// build explode(array<int>, array<str>) expression
Expression[] args = {SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE)),
SlotReference.of("str", ArrayType.of(StringType.INSTANCE))};
Explode explode = new Explode(args);
ExplodeV2 explode = new ExplodeV2(args);
// check signature
List<FunctionSignature> signatures = explode.getSignatures();
@ -65,7 +65,7 @@ public class ExplodeTest {
public void testGetSignaturesWithNull() {
// build explode(null, array<int>) expression
Expression[] args = { SlotReference.of("null", NullType.INSTANCE), SlotReference.of("int", ArrayType.of(IntegerType.INSTANCE))};
Explode explode = new Explode(args);
ExplodeV2 explode = new ExplodeV2(args);
// check signature
List<FunctionSignature> signatures = explode.getSignatures();
@ -87,7 +87,7 @@ public class ExplodeTest {
public void testGetSignaturesWithInvalidArgument() {
// build explode(int)
Expression[] args = { SlotReference.of("int", IntegerType.INSTANCE) };
Explode explode = new Explode(args);
ExplodeV2 explode = new ExplodeV2(args);
Assertions.assertThrows(AnalysisException.class, explode::getSignatures);
}