[fix](nereids)fix some nereids planner bugs (#19509)

1.some encrypt and decrypt functions have wrong blockEncryptionMode
2.topN node should compare tuples from intermediate_row_desc with first_sort_slot.tuple_id
3.must keep the limit if it's an uncorrelated in-subquery with limit on sort, like select a from t1 where a in ( select b from t2 order by xx limit yy )
This commit is contained in:
starocean999
2023-05-12 09:06:16 +08:00
committed by GitHub
parent a041f8eabe
commit e9392780a9
17 changed files with 98 additions and 106 deletions

View File

@ -1030,25 +1030,24 @@ public class FunctionCallExpr extends Expr {
}
if (!aesModes.contains(blockEncryptionMode.toUpperCase())) {
throw new AnalysisException("session variable block_encryption_mode is invalid with aes");
}
if (children.size() == 2) {
if (!blockEncryptionMode.toUpperCase().equals("AES_128_ECB")
&& !blockEncryptionMode.toUpperCase().equals("AES_192_ECB")
&& !blockEncryptionMode.toUpperCase().equals("AES_256_ECB")) {
if (fnName.getFunction().equalsIgnoreCase("aes_decrypt_v2")) {
boolean isECB = blockEncryptionMode.equalsIgnoreCase("AES_128_ECB")
|| blockEncryptionMode.equalsIgnoreCase("AES_192_ECB")
|| blockEncryptionMode.equalsIgnoreCase("AES_256_ECB");
if (fnName.getFunction().equalsIgnoreCase("aes_decrypt_v2")) {
if (!isECB) {
throw new AnalysisException(
"Incorrect parameter count in the call to native function 'aes_decrypt'");
} else if (fnName.getFunction().equalsIgnoreCase("aes_encrypt_v2")) {
}
} else if (fnName.getFunction().equalsIgnoreCase("aes_encrypt_v2")) {
if (!isECB) {
throw new AnalysisException(
"Incorrect parameter count in the call to native function 'aes_encrypt'");
} else {
blockEncryptionMode = "AES_128_ECB";
}
} else if ((blockEncryptionMode.toUpperCase().equals("AES_192_ECB")
|| blockEncryptionMode.toUpperCase().equals("AES_256_ECB"))
&& !fnName.getFunction().equalsIgnoreCase("aes_decrypt_v2")
&& !fnName.getFunction().equalsIgnoreCase("aes_encrypt_v2")) {
} else {
// if there are only 2 params, we need set encryption mode to AES_128_ECB
// this keeps the behavior consistent with old doris ver.
blockEncryptionMode = "AES_128_ECB";
}
}
@ -1063,7 +1062,6 @@ public class FunctionCallExpr extends Expr {
if (!sm4Modes.contains(blockEncryptionMode.toUpperCase())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with sm4");
}
if (children.size() == 2) {
if (fnName.getFunction().equalsIgnoreCase("sm4_decrypt_v2")) {
@ -1073,7 +1071,11 @@ public class FunctionCallExpr extends Expr {
throw new AnalysisException(
"Incorrect parameter count in the call to native function 'sm4_encrypt'");
} else {
blockEncryptionMode = "AES_128_ECB";
// if there are only 2 params, we need add an empty string as the third param
// and set encryption mode to SM4_128_ECB
// this keeps the behavior consistent with old doris ver.
children.add(new StringLiteral(""));
blockEncryptionMode = "SM4_128_ECB";
}
}
}

View File

@ -21,6 +21,7 @@ import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalSort;
import com.google.common.collect.ImmutableList;
@ -33,6 +34,13 @@ public class EliminateLimitUnderApply extends OneRewriteRuleFactory {
@Override
public Rule build() {
return logicalApply(any(), logicalLimit()).then(apply -> {
if (!apply.isCorrelated() && apply.isIn() && (apply.right().child() instanceof LogicalSort
|| (apply.right().child().children().size() > 0
&& apply.right().child().child(0) instanceof LogicalSort))) {
// must keep the limit if it's an uncorrelated in-subquery with limit on sort
// select a from t1 where a in ( select b from t2 order by xx limit yy )
return null;
}
List<Plan> children = new ImmutableList.Builder<Plan>()
.add(apply.left())
.add(apply.right().child())

View File

@ -17,6 +17,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
@ -62,7 +63,13 @@ public abstract class AesCryptoFunction extends CryptoFunction {
super(name, arguments);
}
/** getDefaultBlockEncryptionMode */
public static StringLiteral getDefaultBlockEncryptionMode() {
return CryptoFunction.getDefaultBlockEncryptionMode("AES_128_ECB");
StringLiteral encryptionMode = CryptoFunction.getDefaultBlockEncryptionMode("AES_128_ECB");
if (!AES_MODES.contains(encryptionMode.getValue())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with aes");
}
return encryptionMode;
}
}

View File

@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@ -57,7 +58,16 @@ public class AesDecrypt extends AesCryptoFunction {
* AesDecrypt
*/
public AesDecrypt(Expression arg0, Expression arg1) {
// if there are only 2 params, we need set encryption mode to AES_128_ECB
// this keeps the behavior consistent with old doris ver.
super("aes_decrypt", arg0, arg1, new StringLiteral("AES_128_ECB"));
// check if encryptionMode from session variables is valid
StringLiteral encryptionMode = CryptoFunction.getDefaultBlockEncryptionMode("AES_128_ECB");
if (!AES_MODES.contains(encryptionMode.getValue())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with aes");
}
}
public AesDecrypt(Expression arg0, Expression arg1, Expression arg2) {

View File

@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@ -57,7 +58,16 @@ public class AesEncrypt extends AesCryptoFunction {
* Some javadoc for checkstyle...
*/
public AesEncrypt(Expression arg0, Expression arg1) {
// if there are only 2 params, we need set encryption mode to AES_128_ECB
// this keeps the behavior consistent with old doris ver.
super("aes_encrypt", arg0, arg1, new StringLiteral("AES_128_ECB"));
// check if encryptionMode from session variables is valid
StringLiteral encryptionMode = CryptoFunction.getDefaultBlockEncryptionMode("AES_128_ECB");
if (!AES_MODES.contains(encryptionMode.getValue())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with aes");
}
}
public AesEncrypt(Expression arg0, Expression arg1, Expression arg2) {

View File

@ -59,6 +59,10 @@ public class If extends ScalarFunction
implements TernaryExpression, ExplicitlyCastableSignature {
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
.args(BooleanType.INSTANCE, DateTimeV2Type.SYSTEM_DEFAULT, DateTimeV2Type.SYSTEM_DEFAULT),
FunctionSignature.ret(DateV2Type.INSTANCE)
.args(BooleanType.INSTANCE, DateV2Type.INSTANCE, DateV2Type.INSTANCE),
FunctionSignature.ret(BooleanType.INSTANCE)
.args(BooleanType.INSTANCE, BooleanType.INSTANCE, BooleanType.INSTANCE),
FunctionSignature.ret(TinyIntType.INSTANCE)
@ -78,10 +82,6 @@ public class If extends ScalarFunction
FunctionSignature.ret(DateTimeType.INSTANCE)
.args(BooleanType.INSTANCE, DateTimeType.INSTANCE, DateTimeType.INSTANCE),
FunctionSignature.ret(DateType.INSTANCE).args(BooleanType.INSTANCE, DateType.INSTANCE, DateType.INSTANCE),
FunctionSignature.ret(DateTimeV2Type.SYSTEM_DEFAULT)
.args(BooleanType.INSTANCE, DateTimeV2Type.SYSTEM_DEFAULT, DateTimeV2Type.SYSTEM_DEFAULT),
FunctionSignature.ret(DateV2Type.INSTANCE)
.args(BooleanType.INSTANCE, DateV2Type.INSTANCE, DateV2Type.INSTANCE),
FunctionSignature.ret(DecimalV2Type.SYSTEM_DEFAULT)
.args(BooleanType.INSTANCE, DecimalV2Type.SYSTEM_DEFAULT, DecimalV2Type.SYSTEM_DEFAULT),
FunctionSignature.ret(DecimalV3Type.WILDCARD)

View File

@ -17,6 +17,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
@ -45,6 +46,11 @@ public abstract class Sm4CryptoFunction extends CryptoFunction {
/** getDefaultBlockEncryptionMode */
static StringLiteral getDefaultBlockEncryptionMode() {
return CryptoFunction.getDefaultBlockEncryptionMode("SM4_128_ECB");
StringLiteral encryptionMode = CryptoFunction.getDefaultBlockEncryptionMode("SM4_128_ECB");
if (!SM4_MODES.contains(encryptionMode.getValue())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with sm4");
}
return encryptionMode;
}
}

View File

@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@ -62,7 +63,17 @@ public class Sm4Decrypt extends Sm4CryptoFunction {
* constructor with 2 arguments.
*/
public Sm4Decrypt(Expression arg0, Expression arg1) {
super("sm4_decrypt", arg0, arg1, new StringLiteral("AES_128_ECB"));
// if there are only 2 params, we need add an empty string as the third param
// and set encryption mode to SM4_128_ECB
// this keeps the behavior consistent with old doris ver.
super("sm4_decrypt", arg0, arg1, new StringLiteral(""), new StringLiteral("SM4_128_ECB"));
// check if encryptionMode from session variables is valid
StringLiteral encryptionMode = CryptoFunction.getDefaultBlockEncryptionMode("SM4_128_ECB");
if (!SM4_MODES.contains(encryptionMode.getValue())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with sm4");
}
}
/**

View File

@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@ -57,7 +58,17 @@ public class Sm4Encrypt extends Sm4CryptoFunction {
* constructor with 2 arguments.
*/
public Sm4Encrypt(Expression arg0, Expression arg1) {
super("sm4_encrypt", arg0, arg1, new StringLiteral("AES_128_ECB"));
// if there are only 2 params, we need add an empty string as the third param
// and set encryption mode to SM4_128_ECB
// this keeps the behavior consistent with old doris ver.
super("sm4_encrypt", arg0, arg1, new StringLiteral(""), new StringLiteral("SM4_128_ECB"));
// check if encryptionMode from session variables is valid
StringLiteral encryptionMode = CryptoFunction.getDefaultBlockEncryptionMode("SM4_128_ECB");
if (!SM4_MODES.contains(encryptionMode.getValue())) {
throw new AnalysisException(
"session variable block_encryption_mode is invalid with sm4");
}
}
/**