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 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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,35 @@ 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;

/**
* 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;

/**
* Max DECIMAL scale is implementation-defined.
*
Expand All @@ -116,12 +131,32 @@ 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;

/**
* 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 +582,133 @@ public static HybridTimestamp clusterWideEnsuredActivationTimestamp(long activat
return defaultZone != null ? defaultZone.id() : null;
}


/**
* Returns the maximum supported precision for given type or {@code -1} if the type does not support precision.
*
* @param columnType Column type
* @return Maximum precision
*/
public static int getMaxPrecision(ColumnType columnType) {
if (!columnType.precisionAllowed()) {
return -MIN_DECIMAL_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 {@code -1} if the type does not support precision.
*
* @param columnType Column type
* @return Minimum precision
*/
public static int getMinPrecision(ColumnType columnType) {
if (!columnType.precisionAllowed()) {
return -1;
} 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 {@code -1} if the type does not support length.
*
* @param columnType Column type
* @return Maximum length
*/
public static int getMaxLength(ColumnType columnType) {
if (!columnType.lengthAllowed()) {
return -1;
} 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 {@code -1} if the type does not support length.
*
* @param columnType Column type
* @return Minimum length
*/
public static int getMinLength(ColumnType columnType) {
if (!columnType.lengthAllowed()) {
return -1;
} 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 {@code -1} if the type does not support scale.
*
* @param columnType Column type
* @return Maximum scale
*/
public static int getMaxScale(ColumnType columnType) {
if (!columnType.scaleAllowed()) {
return -1;
} 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 {@code -1} if the type does not support scale.
*
* @param columnType Column type
* @return Minimum scale
*/
public static int getMinScale(ColumnType columnType) {
if (!columnType.scaleAllowed()) {
return -1;
} 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