Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string that is longer than 65536 characters #5119

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
76386ad
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Jan 24, 2025
caf4c22
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Jan 31, 2025
f1ff695
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Jan 31, 2025
42f4b71
Merge branch 'main' into ignite-24153-Sql-Dml-It-is-not-possible-to-i…
lowka Feb 3, 2025
0dc5a80
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 4, 2025
cb63b51
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 4, 2025
c1f33eb
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 4, 2025
b3d043d
IGNITE-22405: Sql. Implement log10 function based on java Math.log10 …
lowka Feb 4, 2025
1f678ac
IGNITE-22405: Sql. Implement log10 function based on java Math.log10 …
lowka Feb 4, 2025
584c8c4
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 5, 2025
a2ca9f6
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 5, 2025
b2fbb72
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 5, 2025
f878e4c
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 5, 2025
6a6262b
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 6, 2025
e1b6b09
Merge branch 'main' into ignite-24153-Sql-Dml-It-is-not-possible-to-i…
lowka Feb 6, 2025
b5aebf0
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 6, 2025
778d8e9
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 6, 2025
6e592f9
IGNITE-24153: Sql. Dml. It is not possible to insert a varchar string…
lowka Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,45 @@ public class CatalogUtils {
*/
public static final int DEFAULT_SCALE = 0;

/**
* Minimum precision for TIME and TIMESTAMP types.
*/
public static final int MIN_TIME_PRECISION = 0;

/**
* Maximum TIME and TIMESTAMP precision is implementation-defined.
*
* <p>SQL`16 part 2 section 6.1 syntax rule 38
*/
public static final int MAX_TIME_PRECISION = NativeTypes.MAX_TIME_PRECISION;

/**
* Unspecified precision.
*/
public static final int UNSPECIFIED_PRECISION = -1;

/**
* Minimum DECIMAL precision.
*/
public static final int MIN_DECIMAL_PRECISION = 1;

/**
* Max DECIMAL precision is implementation-defined.
*
* <p>SQL`16 part 2 section 6.1 syntax rule 25
*/
public static final int MAX_DECIMAL_PRECISION = Short.MAX_VALUE;

/**
* Minimum DECIMAL scale.
*/
public static final int MIN_DECIMAL_SCALE = 0;

/**
* Unspecified scale.
*/
public static final int UNSPECIFIED_SCALE = -1;

/**
* Max DECIMAL scale is implementation-defined.
*
Expand All @@ -116,12 +141,37 @@ public class CatalogUtils {
public static final int DEFAULT_LENGTH = 1;

/**
* Max length for VARCHAR and VARBINARY is implementation defined.
* Default length for VARCHAR and VARBINARY is implementation defined.
*
* <p>SQL`16 part 2 section 6.1 syntax rule 8
*/
public static final int DEFAULT_VARLEN_LENGTH = 2 << 15;

/**
* Maximum length for VARCHAR and VARBINARY types.
*/
public static final int MAX_VARLEN_LENGTH = 2 << 15;

/**
* Minimum length for VARCHAR and VARBINARY types.
*/
public static final int MIN_VARLEN_PRECISION = 1;

/**
* Unspecified length.
*/
public static final int UNSPECIFIED_LENGTH = -1;

/**
* Minimum precision for interval types.
*/
public static final int MIN_INTERVAL_TYPE_PRECISION = 1;

/**
* Maximum precision for interval types.
*/
public static final int MAX_INTERVAL_TYPE_PRECISION = 10;

public static final ConsistencyMode DEFAULT_CONSISTENCY_MODE = ConsistencyMode.STRONG_CONSISTENCY;

private static final Map<ColumnType, Set<ColumnType>> ALTER_COLUMN_TYPE_TRANSITIONS = new EnumMap<>(ColumnType.class);
Expand Down Expand Up @@ -547,6 +597,133 @@ public static HybridTimestamp clusterWideEnsuredActivationTimestamp(long activat
return defaultZone != null ? defaultZone.id() : null;
}


/**
* Returns the maximum supported precision for given type or {@link #UNSPECIFIED_PRECISION} if the type does not support precision.
ygerzhedovich marked this conversation as resolved.
Show resolved Hide resolved
*
* @param columnType Column type.
* @return Maximum precision.
*/
public static int getMaxPrecision(ColumnType columnType) {
if (!columnType.precisionAllowed()) {
return UNSPECIFIED_PRECISION;
} else {
switch (columnType) {
case DECIMAL:
return MAX_DECIMAL_PRECISION;
case TIME:
case DATETIME:
case TIMESTAMP:
return MAX_TIME_PRECISION;
case DURATION:
case PERIOD:
return MAX_INTERVAL_TYPE_PRECISION;
default:
throw new IllegalArgumentException("Unexpected column type: " + columnType);
}
}
}

/**
* Returns the minimum supported precision for given type or {@link #UNSPECIFIED_PRECISION} if the type does not support precision.
*
* @param columnType Column type.
* @return Minimum precision.
*/
public static int getMinPrecision(ColumnType columnType) {
if (!columnType.precisionAllowed()) {
return UNSPECIFIED_PRECISION;
} else {
switch (columnType) {
case DECIMAL:
return MIN_DECIMAL_PRECISION;
case TIME:
case DATETIME:
case TIMESTAMP:
return MIN_TIME_PRECISION;
case DURATION:
case PERIOD:
return MIN_INTERVAL_TYPE_PRECISION;
default:
throw new IllegalArgumentException("Unexpected column type: " + columnType);
}
}
}

/**
* Returns the maximum supported length for given type or {@link #UNSPECIFIED_LENGTH} if the type does not support length.
*
* @param columnType Column type.
* @return Maximum length.
*/
public static int getMaxLength(ColumnType columnType) {
if (!columnType.lengthAllowed()) {
return UNSPECIFIED_LENGTH;
} else {
switch (columnType) {
case STRING:
case BYTE_ARRAY:
return MAX_VARLEN_LENGTH;
default:
throw new IllegalArgumentException("Unexpected column type: " + columnType);
}
}
}

/**
* Returns the minimum supported length for given type or {@link #UNSPECIFIED_LENGTH} if the type does not support length.
*
* @param columnType Column type.
* @return Minimum length.
*/
public static int getMinLength(ColumnType columnType) {
if (!columnType.lengthAllowed()) {
return UNSPECIFIED_LENGTH;
} else {
switch (columnType) {
case STRING:
case BYTE_ARRAY:
return MIN_VARLEN_PRECISION;
default:
throw new IllegalArgumentException("Unexpected column type: " + columnType);
}
}
}

/**
* Returns the maximum supported scale for given type or {@link #UNSPECIFIED_SCALE} if the type does not support scale.
*
* @param columnType Column type.
* @return Maximum scale.
*/
public static int getMaxScale(ColumnType columnType) {
if (!columnType.scaleAllowed()) {
return UNSPECIFIED_SCALE;
} else {
if (columnType == ColumnType.DECIMAL) {
return MAX_DECIMAL_SCALE;
}
throw new IllegalArgumentException("Unexpected column type: " + columnType);
}
}

/**
* Returns the minimum supported scale for given type or {@link #UNSPECIFIED_SCALE} if the type does not support scale.
*
* @param columnType Column type.
* @return Minimum scale.
*/
public static int getMinScale(ColumnType columnType) {
if (!columnType.scaleAllowed()) {
return UNSPECIFIED_SCALE;
} else {
if (columnType == ColumnType.DECIMAL) {
return MIN_DECIMAL_SCALE;
}
throw new IllegalArgumentException("Unexpected column type: " + columnType);
}
}

/**
* Check if provided default value is a constant or a functional default of supported function, or fail otherwise.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@
/** Defines a particular column within table. */
public class ColumnParams {
public static final String ERR_COL_PARAM_NOT_APPLICABLE = "{} is not applicable for column '{}' of type '{}'";
public static final String ERR_COL_PARAM_VALIDATION = "{} for column '{}' of type '{}' must be non-negative";
public static final String ERR_COL_PARAM_DEFINITION = "{} definition is necessary for column '{}' of type '{}'";
public static final String ERR_COL_POSITIVE_PARAM_VALIDATION = "{} for column '{}' of type '{}' must be at least 1";
public static final String ERR_COL_INVALID_TYPE_PARAM = "{} for column `{}` of type {} {} must be between {} and {}";

/** Creates parameters builder. */
public static Builder builder() {
Expand Down Expand Up @@ -236,16 +235,9 @@ private void validate() {
boolean validatePrecision = params.type.precisionAllowed();
boolean validateScale = params.type.scaleAllowed();
boolean validateLength = params.type.lengthAllowed();
Integer length = params.length();

if (validateLength) {
if (length == null) {
throw new CatalogValidationException(format(ERR_COL_PARAM_DEFINITION, "Length", params.name(), params.type()));
}

if (length < 1) {
throw new CatalogValidationException(format(ERR_COL_POSITIVE_PARAM_VALIDATION, "Length", params.name(), params.type()));
}
validateLength(params);
} else {
if (params.length() != null) {
throw new CatalogValidationException(format(ERR_COL_PARAM_NOT_APPLICABLE, "Length", params.name(), params.type()));
Expand Down Expand Up @@ -275,28 +267,62 @@ private void validate() {
}
}

private static void validateLength(ColumnParams params) {
Integer length = params.length();
String name = params.name();
ColumnType type = params.type();

int minLength = CatalogUtils.getMinLength(type);
int maxLength = CatalogUtils.getMaxLength(type);

validateTypeParameter(name, type, "Length", length, minLength, maxLength);
}

private static void validatePrecision(ColumnParams params) {
Integer precision = params.precision();
String name = params.name();
ColumnType type = params.type();

if (precision == null) {
throw new CatalogValidationException(format(ERR_COL_PARAM_DEFINITION, "Precision", params.name(), params.type()));
}
int minPrecision = CatalogUtils.getMinPrecision(type);
int maxPrecision = CatalogUtils.getMaxPrecision(type);

if (precision < 0) {
throw new CatalogValidationException(format(ERR_COL_PARAM_VALIDATION, "Precision", params.name(), params.type()));
}
validateTypeParameter(name, type, "Precision", precision, minPrecision, maxPrecision);
}

private static void validateScale(ColumnParams params) {
Integer scale = params.scale();
String name = params.name();
ColumnType type = params.type();

if (scale == null) {
throw new CatalogValidationException(format(ERR_COL_PARAM_DEFINITION, "Scale", params.name(), params.type()));
}
int minScale = CatalogUtils.getMinScale(type);
int maxScale = CatalogUtils.getMaxScale(type);

if (scale < 0) {
throw new CatalogValidationException(format(ERR_COL_PARAM_VALIDATION, "Scale", params.name(), params.type()));
}
validateTypeParameter(name, type, "Scale", scale, minScale, maxScale);
}
}

private static void validateTypeParameter(
String colName,
ColumnType type,
String paramName,
@Nullable Integer value,
int min,
int max
) {
if (value == null) {
throw new CatalogValidationException(format(ERR_COL_PARAM_DEFINITION, paramName, colName, type));
}

if (value < min || value > max) {
String errorMessage = format(ERR_COL_INVALID_TYPE_PARAM,
paramName,
colName,
type,
value,
min,
max
);
throw new CatalogValidationException(errorMessage);
}
}
}
Loading