[Enchancement](Agg State) storage function name and result is nullable in agg state type (#20298)

storage function name and result is nullable in agg state type
This commit is contained in:
Pxl
2023-06-04 22:44:48 +08:00
committed by GitHub
parent e6f395c9da
commit 8e39f0cf6b
25 changed files with 386 additions and 154 deletions

View File

@ -0,0 +1,134 @@
// 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.catalog;
import org.apache.doris.thrift.TTypeDesc;
import org.apache.doris.thrift.TTypeNode;
import com.google.common.base.Preconditions;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class AggStateType extends ScalarType {
@SerializedName(value = "subTypes")
private List<Type> subTypes;
@SerializedName(value = "subTypeNullables")
private List<Boolean> subTypeNullables;
@SerializedName(value = "resultIsNullable")
private Boolean resultIsNullable;
@SerializedName(value = "functionName")
private String functionName;
public AggStateType(String functionName, Boolean resultIsNullable, List<Type> subTypes,
List<Boolean> subTypeNullables) {
super(PrimitiveType.AGG_STATE);
Preconditions.checkState((subTypes == null) == (subTypeNullables == null));
if (subTypes != null && subTypeNullables != null) {
Preconditions.checkState(subTypes.size() == subTypeNullables.size(),
"AggStateType' subTypes.size()!=subTypeNullables.size()");
}
this.functionName = functionName;
this.subTypes = subTypes;
this.subTypeNullables = subTypeNullables;
this.resultIsNullable = resultIsNullable;
}
public List<Type> getSubTypes() {
return subTypes;
}
public List<Boolean> getSubTypeNullables() {
return subTypeNullables;
}
public String getFunctionName() {
return functionName;
}
public boolean getResultIsNullable() {
return resultIsNullable;
}
@Override
public String toSql(int depth) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("agg_state(");
for (int i = 0; i < subTypes.size(); i++) {
if (i > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(subTypes.get(i).toSql());
if (subTypeNullables.get(i)) {
stringBuilder.append(" NULL");
}
}
stringBuilder.append(")");
return stringBuilder.toString();
}
@Override
public void toThrift(TTypeDesc container) {
super.toThrift(container);
if (subTypes != null) {
List<TTypeDesc> types = new ArrayList<TTypeDesc>();
for (int i = 0; i < subTypes.size(); i++) {
TTypeDesc desc = new TTypeDesc();
desc.setTypes(new ArrayList<TTypeNode>());
subTypes.get(i).toThrift(desc);
desc.setIsNullable(subTypeNullables.get(i));
types.add(desc);
}
container.setSubTypes(types);
}
container.setResultIsNullable(resultIsNullable);
container.setFunctionName(functionName);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof AggStateType)) {
return false;
}
AggStateType other = (AggStateType) o;
if ((subTypes == null) != (other.getSubTypes() == null)) {
return false;
}
if (subTypes == null) {
return true;
}
int subTypeNumber = subTypeNullables.size();
if (subTypeNumber != other.subTypeNullables.size()) {
return false;
}
for (int i = 0; i < subTypeNumber; i++) {
if (!subTypeNullables.get(i).equals(other.subTypeNullables.get(i))) {
return false;
}
if (!subTypes.get(i).equals(other.subTypes.get(i))) {
return false;
}
}
return true;
}
}

View File

@ -31,8 +31,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
@ -125,30 +123,10 @@ public class ScalarType extends Type {
@SerializedName(value = "lenStr")
private String lenStr;
@SerializedName(value = "subTypes")
private List<Type> subTypes;
@SerializedName(value = "subTypeNullables")
private List<Boolean> subTypeNullables;
public List<Type> getSubTypes() {
return subTypes;
}
public List<Boolean> getSubTypeNullables() {
return subTypeNullables;
}
public ScalarType(PrimitiveType type) {
this.type = type;
}
public ScalarType(List<Type> subTypes, List<Boolean> subTypeNullables) {
this.type = PrimitiveType.AGG_STATE;
this.subTypes = subTypes;
this.subTypeNullables = subTypeNullables;
}
public static ScalarType createType(PrimitiveType type, int len, int precision, int scale) {
switch (type) {
case CHAR:
@ -667,17 +645,7 @@ public class ScalarType extends Type {
stringBuilder.append("json");
break;
case AGG_STATE:
stringBuilder.append("agg_state(");
for (int i = 0; i < subTypes.size(); i++) {
if (i > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(subTypes.get(i).toSql());
if (subTypeNullables.get(i)) {
stringBuilder.append(" NULL");
}
}
stringBuilder.append(")");
stringBuilder.append("agg_state(unknown)");
break;
default:
stringBuilder.append("unknown type: " + type.toString());
@ -723,18 +691,6 @@ public class ScalarType extends Type {
break;
}
node.setScalarType(scalarType);
if (subTypes != null) {
List<TTypeDesc> types = new ArrayList<TTypeDesc>();
for (int i = 0; i < subTypes.size(); i++) {
TTypeDesc desc = new TTypeDesc();
desc.setTypes(new ArrayList<TTypeNode>());
subTypes.get(i).toThrift(desc);
desc.setIsNullable(subTypeNullables.get(i));
types.add(desc);
}
container.setSubTypes(types);
}
}
public int decimalPrecision() {
@ -908,22 +864,6 @@ public class ScalarType extends Type {
return false;
}
ScalarType other = (ScalarType) o;
if (this.isAggStateType() && other.isAggStateType()) {
int subTypeNumber = subTypeNullables.size();
if (subTypeNumber != other.subTypeNullables.size()) {
return false;
}
for (int i = 0; i < subTypeNumber; i++) {
if (!subTypeNullables.get(i).equals(other.subTypeNullables.get(i))) {
return false;
}
if (!subTypes.get(i).equals(other.subTypes.get(i))) {
return false;
}
}
return true;
}
if ((this.isDatetimeV2() && other.isDatetimeV2()) || (this.isTimeV2() && other.isTimeV2())) {
return this.decimalScale() == other.decimalScale();
}

View File

@ -102,7 +102,7 @@ public abstract class Type {
public static final ScalarType CHAR = ScalarType.createCharType(-1);
public static final ScalarType BITMAP = new ScalarType(PrimitiveType.BITMAP);
public static final ScalarType QUANTILE_STATE = new ScalarType(PrimitiveType.QUANTILE_STATE);
public static final ScalarType AGG_STATE = new ScalarType(PrimitiveType.AGG_STATE);
public static final AggStateType AGG_STATE = new AggStateType(null, null, null, null);
public static final ScalarType LAMBDA_FUNCTION = new ScalarType(PrimitiveType.LAMBDA_FUNCTION);
// Only used for alias function, to represent any type in function args
public static final ScalarType ALL = new ScalarType(PrimitiveType.ALL);