{"record":{"id":"a970f46f770756bf","repo":"apache/iceberg","slug":"expected-truncation-width-to-be-tinyint-shortint","errorCode":null,"errorMessage":"Expected truncation width to be tinyint, shortint or int","messagePattern":"Expected truncation width to be tinyint, shortint or int","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/functions/TruncateFunction.java","lineNumber":72,"sourceCode":"public class TruncateFunction implements UnboundFunction {\n\n  private static final int WIDTH_ORDINAL = 0;\n  private static final int VALUE_ORDINAL = 1;\n\n  private static final Set<DataType> SUPPORTED_WIDTH_TYPES =\n      ImmutableSet.of(DataTypes.ByteType, DataTypes.ShortType, DataTypes.IntegerType);\n\n  @Override\n  public BoundFunction bind(StructType inputType) {\n    if (inputType.size() != 2) {\n      throw new UnsupportedOperationException(\"Wrong number of inputs (expected width and value)\");\n    }\n\n    StructField widthField = inputType.fields()[WIDTH_ORDINAL];\n    StructField valueField = inputType.fields()[VALUE_ORDINAL];\n\n    if (!SUPPORTED_WIDTH_TYPES.contains(widthField.dataType())) {\n      throw new UnsupportedOperationException(\n          \"Expected truncation width to be tinyint, shortint or int\");\n    }\n\n    DataType valueType = valueField.dataType();\n    if (valueType instanceof ByteType) {\n      return new TruncateTinyInt();\n    } else if (valueType instanceof ShortType) {\n      return new TruncateSmallInt();\n    } else if (valueType instanceof IntegerType) {\n      return new TruncateInt();\n    } else if (valueType instanceof LongType) {\n      return new TruncateBigInt();\n    } else if (valueType instanceof DecimalType) {\n      return new TruncateDecimal(\n          ((DecimalType) valueType).precision(), ((DecimalType) valueType).scale());\n    } else if (valueType instanceof StringType) {\n      return new TruncateString();\n    } else if (valueType instanceof BinaryType) {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/functions/TruncateFunction.java#L54-L90","documentation":"The truncation width argument must be ByteType (tinyint), ShortType (shortint/smallint), or IntegerType (int). `bind` throws this UnsupportedOperationException when the width field has any other type (e.g. long, string, decimal). The width controls how many bytes/characters to keep and is intentionally restricted.","triggerScenarios":"Calling `truncate` with a width literal Spark infers as BIGINT (e.g. `truncate(10L, col)`), or passing a width column of type long/string/decimal.","commonSituations":"Spark literal inference producing BIGINT widths; programmatic calls passing Long instead of Int; copying examples from engines where literal defaults differ.","solutions":["Cast the width to int: `truncate(CAST(20 AS INT), col)`.","Use an int-binding literal: `truncate(20, col)` in versions where integer literals are INT by default.","In code, pass an IntegerType literal (e.g. functions.lit(20)) rather than a long."],"exampleFix":"// before\nspark.sql(\"SELECT truncate(10L, s) FROM t\")\n// after\nspark.sql(\"SELECT truncate(CAST(10 AS INT), s) FROM t\")","handlingStrategy":"validation","validationCode":"// ensure the width literal binds as int\nspark.sql(\"SELECT typeof(CAST(10 AS INT))\").show(); // 'int'\n// or in code: functions.lit(10) typed as int, never lit(10L)","typeGuard":null,"tryCatchPattern":"try { df.select(functions.callUDF(\"truncate\", functions.lit(10), functions.col(\"s\"))); } catch (UnsupportedOperationException e) { if (e.getMessage().contains(\"tinyint, shortint or int\")) { /* cast width to INT */ } throw e; }","preventionTips":["CAST the width to INT when literal inference is uncertain.","Never pass long/string/decimal widths.","Verify inferred literal types with typeof() during query development."],"tags":["spark","sql-function","type-mismatch","width"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}