From 49409a6a438a7ae431dc62898d0732ba212cfdea Mon Sep 17 00:00:00 2001 From: "Na, Hyunik" <67700070+hyunikn@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:55:44 +0900 Subject: [PATCH 1/4] [CBRD-25685] give error messages to type casting done in PL server (#5629) * give error messages to type casting done in PL server --- .../com/cubrid/jsp/value/BooleanValue.java | 5 ++ .../java/com/cubrid/jsp/value/ByteValue.java | 5 ++ .../java/com/cubrid/jsp/value/DateValue.java | 5 ++ .../com/cubrid/jsp/value/DatetimeValue.java | 5 ++ .../com/cubrid/jsp/value/DoubleValue.java | 5 ++ .../java/com/cubrid/jsp/value/FloatValue.java | 5 ++ .../java/com/cubrid/jsp/value/IntValue.java | 5 ++ .../java/com/cubrid/jsp/value/LongValue.java | 5 ++ .../java/com/cubrid/jsp/value/NullValue.java | 5 ++ .../com/cubrid/jsp/value/NumericValue.java | 5 ++ .../java/com/cubrid/jsp/value/OidValue.java | 5 ++ .../com/cubrid/jsp/value/ResultSetValue.java | 5 ++ .../java/com/cubrid/jsp/value/SetValue.java | 5 ++ .../java/com/cubrid/jsp/value/ShortValue.java | 5 ++ .../com/cubrid/jsp/value/StringValue.java | 4 ++ .../java/com/cubrid/jsp/value/TimeValue.java | 5 ++ .../com/cubrid/jsp/value/TimestampValue.java | 5 ++ .../main/java/com/cubrid/jsp/value/Value.java | 72 +++++++++++++------ 18 files changed, 136 insertions(+), 20 deletions(-) diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/BooleanValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/BooleanValue.java index 732c2c7546..fce60cfda7 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/BooleanValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/BooleanValue.java @@ -34,6 +34,11 @@ import com.cubrid.jsp.exception.TypeMismatchException; public class BooleanValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_BOOLEAN; + } + private byte value = 0; public BooleanValue(boolean b) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ByteValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ByteValue.java index a3090b9c65..070f2279da 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ByteValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ByteValue.java @@ -35,6 +35,11 @@ import java.math.BigDecimal; public class ByteValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_BYTE; + } + private byte value; public ByteValue(byte value) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DateValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DateValue.java index 8b93a03ade..3c9a87e96a 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DateValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DateValue.java @@ -38,6 +38,11 @@ import java.util.Calendar; public class DateValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_DATE; + } + private Date date; public DateValue(int year, int mon, int day) throws TypeMismatchException { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DatetimeValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DatetimeValue.java index 7391a53f14..e90af1aaf0 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DatetimeValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DatetimeValue.java @@ -39,6 +39,11 @@ import java.util.Calendar; public class DatetimeValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_DATETIME; + } + private Timestamp timestamp; public DatetimeValue(int year, int mon, int day, int hour, int min, int sec, int msec) diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DoubleValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DoubleValue.java index eb14f1802d..95814c8784 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DoubleValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/DoubleValue.java @@ -38,6 +38,11 @@ import java.sql.Timestamp; public class DoubleValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_DOUBLE; + } + private double value; public DoubleValue(double value) throws TypeMismatchException { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/FloatValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/FloatValue.java index c18df5e16a..3aec4f44a1 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/FloatValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/FloatValue.java @@ -38,6 +38,11 @@ import java.sql.Timestamp; public class FloatValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_FLOAT; + } + private float value; public FloatValue(float value) throws TypeMismatchException { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/IntValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/IntValue.java index 1e2aad20ec..2e0f3187c5 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/IntValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/IntValue.java @@ -38,6 +38,11 @@ import java.sql.Timestamp; public class IntValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_INT; + } + private int value; public IntValue(int value) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/LongValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/LongValue.java index 2414491f67..bbc4a22709 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/LongValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/LongValue.java @@ -38,6 +38,11 @@ import java.sql.Timestamp; public class LongValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_BIGINT; + } + private long value; public LongValue(long value) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NullValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NullValue.java index e8ff4b7946..febe6e9c1e 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NullValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NullValue.java @@ -41,6 +41,11 @@ import java.sql.Timestamp; public class NullValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_NULL; + } + public NullValue() { super(); } diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NumericValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NumericValue.java index adf5596b34..d9ac6974e7 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NumericValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/NumericValue.java @@ -37,6 +37,11 @@ import java.sql.Timestamp; public class NumericValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_NUMERIC; + } + private BigDecimal value; public NumericValue(String value) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/OidValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/OidValue.java index 39390a97d1..2cee524859 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/OidValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/OidValue.java @@ -41,6 +41,11 @@ import java.sql.SQLException; public class OidValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_OID; + } + private SOID oidValue = null; private CUBRIDOID oidObject = null; diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ResultSetValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ResultSetValue.java index 2096e703cf..04f048d6cf 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ResultSetValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ResultSetValue.java @@ -37,6 +37,11 @@ import java.sql.ResultSet; public class ResultSetValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_RESULTSET; + } + private long queryId; private ResultSet rset = null; diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/SetValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/SetValue.java index d8370f1f21..15050272d9 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/SetValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/SetValue.java @@ -39,6 +39,11 @@ import java.sql.Timestamp; public class SetValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_SET; + } + private Object[] values; public SetValue(Value[] args) throws TypeMismatchException { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ShortValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ShortValue.java index 56f54abbc5..5e3a5cb55a 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ShortValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/ShortValue.java @@ -38,6 +38,11 @@ import java.sql.Timestamp; public class ShortValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_SHORT; + } + private short value; public ShortValue(short value) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/StringValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/StringValue.java index e06ed04e5c..cc29c39221 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/StringValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/StringValue.java @@ -40,6 +40,10 @@ public class StringValue extends Value { + protected String getTypeName() { + return TYPE_NAME_STRING; + } + private String value; public StringValue(String value) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimeValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimeValue.java index 82e3f64cc8..ac74140133 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimeValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimeValue.java @@ -37,6 +37,11 @@ import java.util.Calendar; public class TimeValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_TIME; + } + private Time time; public TimeValue(int hour, int min, int sec) { diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimestampValue.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimestampValue.java index c9235f3f01..9757907df4 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimestampValue.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/TimestampValue.java @@ -39,6 +39,11 @@ import java.util.Calendar; public class TimestampValue extends Value { + + protected String getTypeName() { + return TYPE_NAME_TIMESTAMP; + } + private Timestamp timestamp; public TimestampValue(int year, int mon, int day, int hour, int min, int sec) diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/Value.java b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/Value.java index 485fbab2ba..543f230e07 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/Value.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/jsp/value/Value.java @@ -66,31 +66,31 @@ public int getMode() { } public byte toByte() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_BYTE)); } public short toShort() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_SHORT)); } public int toInt() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_INT)); } public long toLong() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_BIGINT)); } public float toFloat() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_FLOAT)); } public double toDouble() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_DOUBLE)); } public Byte toByteObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_BYTE)); } public byte[] toByteArray() throws TypeMismatchException { @@ -102,7 +102,7 @@ public byte[][] toByteArrayArray() throws TypeMismatchException { } public Short toShortObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_SHORT)); } public short[] toShortArray() throws TypeMismatchException { @@ -114,7 +114,7 @@ public short[][] toShortArrayArray() throws TypeMismatchException { } public Integer toIntegerObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_INT)); } public int[] toIntegerArray() throws TypeMismatchException { @@ -126,7 +126,7 @@ public int[][] toIntegerArrayArray() throws TypeMismatchException { } public Long toLongObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_BIGINT)); } public long[] toLongArray() throws TypeMismatchException { @@ -138,7 +138,7 @@ public long[][] toLongArrayArray() throws TypeMismatchException { } public Float toFloatObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_FLOAT)); } public float[] toFloatArray() throws TypeMismatchException { @@ -150,7 +150,7 @@ public float[][] toFloatArrayArray() throws TypeMismatchException { } public Double toDoubleObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_DOUBLE)); } public double[] toDoubleArray() throws TypeMismatchException { @@ -162,7 +162,7 @@ public double[][] toDoubleArrayArray() throws TypeMismatchException { } public Object toObject() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_OBJECT)); } public Object[] toObjectArray() throws TypeMismatchException { @@ -174,7 +174,7 @@ public Object[][] toObjectArrayArray() throws TypeMismatchException { } public Date toDate() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_DATE)); } public Date[] toDateArray() throws TypeMismatchException { @@ -186,7 +186,7 @@ public Date[][] toDateArrayArray() throws TypeMismatchException { } public Time toTime() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_TIME)); } public Time[] toTimeArray() throws TypeMismatchException { @@ -198,7 +198,7 @@ public Time[][] toTimeArrayArray() throws TypeMismatchException { } public Timestamp toTimestamp() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_TIMESTAMP)); } public Timestamp[] toTimestampArray() throws TypeMismatchException { @@ -210,7 +210,7 @@ public Timestamp[][] toTimestampArrayArray() throws TypeMismatchException { } public Timestamp toDatetime() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_DATETIME)); } public Timestamp[] toDatetimeArray() throws TypeMismatchException { @@ -222,7 +222,7 @@ public Timestamp[][] toDatetimeArrayArray() throws TypeMismatchException { } public BigDecimal toBigDecimal() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_NUMERIC)); } public BigDecimal[] toBigDecimalArray() throws TypeMismatchException { @@ -290,7 +290,7 @@ public Double[][] toDoubleObjArrayArray() throws TypeMismatchException { } public CUBRIDOID toOid() throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_OID)); } public CUBRIDOID[] toOidArray() throws TypeMismatchException { @@ -302,7 +302,7 @@ public CUBRIDOID[][] toOidArrayArray() throws TypeMismatchException { } public ResultSet toResultSet(SUConnection ucon) throws TypeMismatchException { - throw new TypeMismatchException(); + throw new TypeMismatchException(getCastErrMsg(TYPE_NAME_RESULTSET)); } public ResultSet[] toResultSetArray(SUConnection ucon) throws TypeMismatchException { @@ -328,4 +328,36 @@ public int getDbType() { public void setDbType(int type) { dbType = type; } + + // ----------------------------------------------------- + + private String getCastErrMsg(String targetType) { + return String.format("cannot convert %s to %s", getTypeName(), targetType); + } + + protected abstract String getTypeName(); + + protected static final String TYPE_NAME_NULL = "NULL"; + protected static final String TYPE_NAME_OBJECT = "OBJECT"; + + protected static final String TYPE_NAME_BOOLEAN = "BOOLEAN"; + protected static final String TYPE_NAME_STRING = "STRING"; + + protected static final String TYPE_NAME_BYTE = "BYTE"; + protected static final String TYPE_NAME_SHORT = "SHORT"; + protected static final String TYPE_NAME_INT = "INT"; + protected static final String TYPE_NAME_BIGINT = "BIGINT"; + protected static final String TYPE_NAME_FLOAT = "FLOAT"; + protected static final String TYPE_NAME_DOUBLE = "DOUBLE"; + protected static final String TYPE_NAME_NUMERIC = "NUMERIC"; + + protected static final String TYPE_NAME_DATE = "DATE"; + protected static final String TYPE_NAME_TIME = "TIME"; + protected static final String TYPE_NAME_DATETIME = "DATETIME"; + protected static final String TYPE_NAME_TIMESTAMP = "TIMESTAMP"; + + protected static final String TYPE_NAME_OID = "OID"; + protected static final String TYPE_NAME_RESULTSET = "RESULTSET"; + protected static final String TYPE_NAME_SET = + "COLLECTION"; // actually, it is not only SET but also MULTISET and LIST } From 9de81a0670f49e1cabf77562b268c0d940434ed0 Mon Sep 17 00:00:00 2001 From: Kisoo Han Date: Wed, 20 Nov 2024 14:16:03 +0900 Subject: [PATCH 2/4] [CBRD-25662] remove trailing slash shown in cubrid broker info (#5633) remove trailing slash shown in cubrid broker info --- src/broker/broker_filename.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/broker/broker_filename.c b/src/broker/broker_filename.c index a14a662eeb..79f461b16f 100644 --- a/src/broker/broker_filename.c +++ b/src/broker/broker_filename.c @@ -350,6 +350,7 @@ make_abs_path (char *dest, const char *subdir, const char *path, size_t dest_len int ret = 0; char buf[BROKER_PATH_MAX * 4]; char new_path[BROKER_PATH_MAX * 4]; + int path_len; if (path == NULL || path[0] == 0) { @@ -364,7 +365,6 @@ make_abs_path (char *dest, const char *subdir, const char *path, size_t dest_len } else { - snprintf (buf, dest_len, "%s%s%s\\%s", get_cubrid_home (), subdir ? "\\" : "", subdir ? subdir : "", path); _fullpath (new_path, buf, dest_len); } @@ -379,6 +379,20 @@ make_abs_path (char *dest, const char *subdir, const char *path, size_t dest_len } #endif + path_len = strlen (new_path) - 1; + while (path_len > 0) + { + if (new_path[path_len] == '/' || new_path[path_len] == '\\') + { + new_path[path_len] = '\0'; + } + else + { + break; + } + path_len--; + } + if (strlen (new_path) < dest_len) { snprintf (dest, dest_len, "%s", new_path); From 0a3df82ef98f0485138f64cb368d5f59ea42b36a Mon Sep 17 00:00:00 2001 From: "Na, Hyunik" <67700070+hyunikn@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:03:25 +0900 Subject: [PATCH 3/4] [CBRD-25682] keep precision and scale of the numeric type when it is a return type specified by %TYPE (#5628) * keep precision and scale of the numeric type when it is a return type specified by %TYPE * minor: add a server log for semantic API errors --- .../plcsql/compiler/ParseTreeConverter.java | 38 +++++++++++-------- .../plcsql/compiler/ast/TypeSpecPercent.java | 7 ++-- .../plcsql/compiler/visitor/TypeChecker.java | 5 +++ 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ParseTreeConverter.java b/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ParseTreeConverter.java index a363a36f90..46ed3aeb40 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ParseTreeConverter.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ParseTreeConverter.java @@ -202,12 +202,14 @@ public void askServerSemanticQuestions() { assert node instanceof TypeSpecPercent; TypeSpecPercent tsp = (TypeSpecPercent) node; - if (tsp.forParameterOrReturn) { - tsp.type = DBTypeAdapter.getValueType(iStore, ct.colType.type); - } else { + if (tsp.typeVisitMode == TYPE_VISIT_NORMAL + || (tsp.typeVisitMode == TYPE_VISIT_RETURN + && ct.colType.type == DBType.DB_NUMERIC)) { tsp.type = DBTypeAdapter.getDeclType( iStore, ct.colType.type, ct.colType.prec, ct.colType.scale); + } else { + tsp.type = DBTypeAdapter.getValueType(iStore, ct.colType.type); } } else { assert false : "unreachable"; @@ -285,10 +287,10 @@ public DeclParamIn visitCursor_parameter(Cursor_parameterContext ctx) { String name = Misc.getNormalizedText(ctx.parameter_name()); TypeSpec typeSpec; try { - forParameterOrReturn = true; + typeVisitMode = TYPE_VISIT_PARAM; typeSpec = (TypeSpec) visit(ctx.type_spec()); } finally { - forParameterOrReturn = false; + typeVisitMode = TYPE_VISIT_NORMAL; } DeclParamIn ret = new DeclParamIn(ctx, name, typeSpec); @@ -302,10 +304,10 @@ public DeclParamIn visitParameter_in(Parameter_inContext ctx) { String name = Misc.getNormalizedText(ctx.parameter_name()); TypeSpec typeSpec; try { - forParameterOrReturn = true; + typeVisitMode = TYPE_VISIT_PARAM; typeSpec = (TypeSpec) visit(ctx.type_spec()); } finally { - forParameterOrReturn = false; + typeVisitMode = TYPE_VISIT_NORMAL; } DeclParamIn ret = new DeclParamIn(ctx, name, typeSpec); @@ -319,10 +321,10 @@ public DeclParamOut visitParameter_out(Parameter_outContext ctx) { String name = Misc.getNormalizedText(ctx.parameter_name()); TypeSpec typeSpec; try { - forParameterOrReturn = true; + typeVisitMode = TYPE_VISIT_PARAM; typeSpec = (TypeSpec) visit(ctx.type_spec()); } finally { - forParameterOrReturn = false; + typeVisitMode = TYPE_VISIT_NORMAL; } boolean alsoIn = ctx.IN() != null || ctx.INOUT() != null; @@ -356,7 +358,7 @@ public TypeSpec visitPercent_type(Percent_typeContext ctx) { } String column = Misc.getNormalizedText(ctx.identifier()); - TypeSpec ret = new TypeSpecPercent(ctx, table, column, forParameterOrReturn); + TypeSpec ret = new TypeSpecPercent(ctx, table, column, typeVisitMode); semanticQuestions.put(ret, new ServerAPI.ColumnType(table, column)); return ret; } @@ -422,7 +424,7 @@ public TypeSpec visitPercent_rowtype(Percent_rowtypeContext ctx) { @Override public TypeSpec visitNumeric_type(Numeric_typeContext ctx) { - if (forParameterOrReturn) { + if (typeVisitMode != TYPE_VISIT_NORMAL) { if (ctx.precision != null) { throw new SemanticError( Misc.getLineColumnOf(ctx), // s091 @@ -464,7 +466,7 @@ public TypeSpec visitNumeric_type(Numeric_typeContext ctx) { @Override public TypeSpec visitChar_type(Char_typeContext ctx) { - if (forParameterOrReturn) { + if (typeVisitMode != TYPE_VISIT_NORMAL) { if (ctx.length != null) { throw new SemanticError( Misc.getLineColumnOf(ctx), // s092 @@ -496,7 +498,7 @@ public TypeSpec visitChar_type(Char_typeContext ctx) { @Override public TypeSpec visitVarchar_type(Varchar_typeContext ctx) { - if (forParameterOrReturn) { + if (typeVisitMode != TYPE_VISIT_NORMAL) { if (ctx.length != null) { throw new SemanticError( Misc.getLineColumnOf(ctx), // s093 @@ -2333,12 +2335,16 @@ private static String unquoteStr(String val) { return val.replace("''", "'"); } + private static final int TYPE_VISIT_NORMAL = 0; + private static final int TYPE_VISIT_PARAM = 1; + private static final int TYPE_VISIT_RETURN = 2; + // -------------------------------------------------------- // Private // -------------------------------------------------------- private InstanceStore iStore; - private boolean forParameterOrReturn = false; + private int typeVisitMode = TYPE_VISIT_NORMAL; private static class UseAndDeclLevel { ParserRuleContext use; @@ -2469,10 +2475,10 @@ private void previsitRoutine_definition( TypeSpec retTypeSpec; try { - forParameterOrReturn = true; + typeVisitMode = TYPE_VISIT_RETURN; retTypeSpec = (TypeSpec) visit(ctx.type_spec()); } finally { - forParameterOrReturn = false; + typeVisitMode = TYPE_VISIT_NORMAL; } Type retType = retTypeSpec.type; diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ast/TypeSpecPercent.java b/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ast/TypeSpecPercent.java index 4c74affb8f..7d923e0164 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ast/TypeSpecPercent.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/ast/TypeSpecPercent.java @@ -42,13 +42,12 @@ public R accept(AstVisitor visitor) { public final String table; public final String column; - public final boolean forParameterOrReturn; + public final int typeVisitMode; - public TypeSpecPercent( - ParserRuleContext ctx, String table, String column, boolean forParameterOrReturn) { + public TypeSpecPercent(ParserRuleContext ctx, String table, String column, int typeVisitMode) { super(ctx, null); // null: unknown yet this.table = table; this.column = column; - this.forParameterOrReturn = forParameterOrReturn; + this.typeVisitMode = typeVisitMode; } } diff --git a/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/visitor/TypeChecker.java b/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/visitor/TypeChecker.java index 42a5045734..68b31c65de 100644 --- a/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/visitor/TypeChecker.java +++ b/pl_engine/pl_server/src/main/java/com/cubrid/plcsql/compiler/visitor/TypeChecker.java @@ -30,6 +30,7 @@ package com.cubrid.plcsql.compiler.visitor; +import com.cubrid.jsp.Server; import com.cubrid.jsp.data.ColumnInfo; import com.cubrid.plcsql.compiler.Coercion; import com.cubrid.plcsql.compiler.CoercionScheme; @@ -641,6 +642,10 @@ public Type visitExprBuiltinFuncCall(ExprBuiltinFuncCall node) { return ret; } else { + Server.log( + String.format( + "semantic check API returned an error (%d, %s) for '%s'", + ss.errCode, ss.errMsg, sql)); throw new SemanticError( Misc.getLineColumnOf(node.ctx), // s235 "function " From 2b1a58494fe7be559b1c7f830de74c07af051d49 Mon Sep 17 00:00:00 2001 From: Ilhan <70995854+xmilex-git@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:50:37 +0900 Subject: [PATCH 4/4] [CBRD-25680] When using a correlated subquery that includes columns from an outer table in the select clause, it is not selected as a cache key (#5623) http://jira.cubrid.org/browse/CBRD-25680 When using a correlated subquery that includes columns from an outer table in the select clause, the subquery cache does not use those columns as keys, resulting in improper caching. Consequently, cache hits occur even in situations where cache misses are expected. To address this, we modified the code to include regu_var from xasl outptr_list as part of the caching key. Additionally, unlike pred, xasl outptr_list uses the outer table as a constant regu_var during joins, which could mistakenly utilize even non-outer columns as cache keys. Therefore, we adjusted the code to only enable caching when there is no table from the subquery that matches the specification. --- src/parser/view_transform.c | 5 ++-- src/parser/xasl_generation.c | 54 ++++++++++++++++++++++++++++++++++++ src/query/regu_var.hpp | 1 + 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/parser/view_transform.c b/src/parser/view_transform.c index e5891c8a29..bcf1d2882d 100644 --- a/src/parser/view_transform.c +++ b/src/parser/view_transform.c @@ -4944,8 +4944,9 @@ mq_rewrite_aggregate_as_derived (PARSER_CONTEXT * parser, PT_NODE * agg_sel) * Therefore, the NO_MERGE hint is not moved to the derived subquery. * Additionally, if the subquery has the QUERY_CACHE hint, it should not be merged, so it is treated together with the NO_MERGE hint. * All hints except for NO_MERGE and QUERY_CACHE are moved to the derived subquery. */ - derived->info.query.q.select.hint = agg_sel->info.query.q.select.hint & ~(PT_HINT_NO_MERGE | PT_HINT_QUERY_CACHE); - agg_sel->info.query.q.select.hint &= (PT_HINT_NO_MERGE | PT_HINT_QUERY_CACHE); + derived->info.query.q.select.hint = + agg_sel->info.query.q.select.hint & ~(PT_HINT_NO_MERGE | PT_HINT_QUERY_CACHE | PT_HINT_NO_SUBQUERY_CACHE); + agg_sel->info.query.q.select.hint &= (PT_HINT_NO_MERGE | PT_HINT_QUERY_CACHE | PT_HINT_NO_SUBQUERY_CACHE); derived->info.query.q.select.leading = agg_sel->info.query.q.select.leading; agg_sel->info.query.q.select.leading = NULL; diff --git a/src/parser/xasl_generation.c b/src/parser/xasl_generation.c index 5dcc23ced1..547ce892ce 100644 --- a/src/parser/xasl_generation.c +++ b/src/parser/xasl_generation.c @@ -10125,6 +10125,7 @@ pt_attribute_to_regu (PARSER_CONTEXT * parser, PT_NODE * attr) { /* The attribute is correlated variable. Find it in an enclosing scope(s). Note that this subquery has * also just been determined to be a correlated subquery. */ + REGU_VARIABLE_SET_FLAG (regu, REGU_VARIABLE_CORRELATED); if (symbols->stack == NULL) { if (!pt_has_error (parser)) @@ -27436,6 +27437,7 @@ pt_make_sq_cache_key_struct (QPROC_DB_VALUE_LIST key_struct, void *p, int type) ACCESS_SPEC_TYPE *spec; PRED_EXPR *pred_src; REGU_VARIABLE *regu_src; + REGU_VARIABLE_LIST regu_var_list_p; if (!p) { return 0; @@ -27546,6 +27548,54 @@ pt_make_sq_cache_key_struct (QPROC_DB_VALUE_LIST key_struct, void *p, int type) cnt += ret; } } + if (xasl_src->outptr_list) + { + regu_var_list_p = xasl_src->outptr_list->valptrp; + for (i = 0; i < xasl_src->outptr_list->valptr_cnt; i++) + { + if (!regu_var_list_p) + { + assert (false); + return ER_FAILED; + } + regu_src = ®u_var_list_p->value; + ret = pt_make_sq_cache_key_struct (key_struct, (void *) regu_src, SQ_TYPE_REGU_VAR); + if (ret == ER_FAILED) + { + return ER_FAILED; + } + else + { + cnt += ret; + } + regu_var_list_p = regu_var_list_p->next; + } + } + if (xasl_src->type == BUILDVALUE_PROC || xasl_src->type == BUILDLIST_PROC) + { + AGGREGATE_TYPE *agg_list = + (xasl_src->type == + BUILDVALUE_PROC) ? xasl_src->proc.buildvalue.agg_list : xasl_src->proc.buildlist.g_agg_list; + while (agg_list) + { + regu_var_list_p = agg_list->operands; + while (regu_var_list_p) + { + ret = pt_make_sq_cache_key_struct (key_struct, (void *) ®u_var_list_p->value, SQ_TYPE_REGU_VAR); + if (ret == ER_FAILED) + { + return ER_FAILED; + } + else + { + cnt += ret; + } + regu_var_list_p = regu_var_list_p->next; + } + agg_list = agg_list->next; + } + + } break; case SQ_TYPE_PRED: pred_src = (PRED_EXPR *) p; @@ -27614,6 +27664,10 @@ pt_make_sq_cache_key_struct (QPROC_DB_VALUE_LIST key_struct, void *p, int type) switch (regu_src->type) { case TYPE_CONSTANT: + if (!REGU_VARIABLE_IS_FLAGED (regu_src, REGU_VARIABLE_CORRELATED)) + { + break; + } ret = pt_make_sq_cache_key_struct (key_struct, (void *) regu_src->value.dbvalptr, SQ_TYPE_DBVAL); if (ret == ER_FAILED) { diff --git a/src/query/regu_var.hpp b/src/query/regu_var.hpp index 672b62d586..7311335fba 100644 --- a/src/query/regu_var.hpp +++ b/src/query/regu_var.hpp @@ -166,6 +166,7 @@ const int REGU_VARIABLE_FETCH_NOT_CONST = 0x80; /* is not constant */ const int REGU_VARIABLE_CLEAR_AT_CLONE_DECACHE = 0x100; /* clears regu variable at clone decache */ const int REGU_VARIABLE_UPD_INS_LIST = 0x200; /* for update or insert query */ const int REGU_VARIABLE_STRICT_TYPE_CAST = 0x400;/* for update or insert query */ +const int REGU_VARIABLE_CORRELATED = 0x800; /* for correlated scalar subquery cache */ class regu_variable_node {