{"record":{"id":"29875bdea0891413","repo":"apache/beam","slug":"expected-non-null-string-literal","errorCode":null,"errorMessage":"Expected non-null String literal","messagePattern":"Expected non-null String literal","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/bigtable/BigtableFilter.java","lineNumber":97,"sourceCode":"        String.format(\"Only one LIKE operation is allowed. Got %s operations\", supported.size()));\n    return translateRexNodeToRowFilter(supported.get(0));\n  }\n\n  private RowFilter translateRexNodeToRowFilter(RexNode node) {\n    checkNodeIsCoposite(node);\n    checkArgument(LIKE.equals(node.getKind()), \"Only LIKE operation is supported.\");\n\n    List<RexLiteral> literals = filterOperands((RexCall) node, RexLiteral.class);\n    List<RexInputRef> inputRefs = filterOperands((RexCall) node, RexInputRef.class);\n\n    checkArgument(literals.size() == 1);\n    checkArgument(inputRefs.size() == 1);\n\n    checkFieldIsKey(inputRefs.get(0));\n    String literal = literals.get(0).getValueAs(String.class);\n\n    if (literal == null) {\n      throw new IllegalArgumentException(\"Expected non-null String literal\");\n    }\n\n    return RowFilter.newBuilder().setRowKeyRegexFilter(byteStringUtf8(literal)).build();\n  }\n\n  private void checkFieldIsKey(RexInputRef inputRef) {\n    String inputFieldName = schema.getField(inputRef.getIndex()).getName();\n    checkArgument(\n        KEY.equals(inputFieldName),\n        \"Only 'key' queries are supported. Got field \" + inputFieldName);\n  }\n\n  private static boolean isSupported(RexNode node) {\n    checkNodeIsCoposite(node);\n    if (!LIKE.equals(node.getKind())) {\n      return false;\n    }\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/bigtable/BigtableFilter.java#L79-L115","documentation":"BigtableFilter.translateRexNodeToRowFilter converts a pushed-down equality filter on the row key into a Bigtable RowFilter regex. The literal operand must be a Java String; if RexLiteral.getValueAs(String.class) returns null (literal is not a string type) it throws IllegalArgumentException because a non-string key comparison cannot be translated to a row-key regex.","triggerScenarios":"Applying a WHERE clause against a Bigtable row-key column with a non-string literal (e.g. rowkey = 123) or with a NULL literal, then calling getFilters → translateRexNodeToRowFilter; literals.get(0).getValueAs(String.class) yields null.","commonSituations":"Comparing the row key to numeric or binary literals; passing NULL comparisons expecting pushdown; column-type mismatches between the schema declaration and query literals.","solutions":["Quote the row-key comparison as a string, e.g. WHERE rowkey = '123'","Avoid pushing NULL/IS NULL filters on the key to Bigtable; handle them in Beam","Cast the literal to the key's declared string type in the query before filtering"],"exampleFix":"// before\nSELECT * FROM bigtable_t WHERE rowkey = 123\n// after\nSELECT * FROM bigtable_t WHERE rowkey = '123'","handlingStrategy":"type-guard","validationCode":"// before pushdown\nRexLiteral lit = literals.get(0);\nString s = lit.getValueAs(String.class);\nif (s == null) throw new IllegalArgumentException(\"row-key filter literal must be a string\");","typeGuard":"boolean isStringLiteral(RexLiteral l) {\n  return l != null && l.getType().getSqlTypeName() == SqlTypeName.VARCHAR && l.getValueAs(String.class) != null;\n}","tryCatchPattern":"try {\n  RowFilter rf = bigtableFilter.getFilters(...);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Expected non-null String literal\")) { /* evaluate filter locally instead */ }\n  throw e;\n}","preventionTips":["Always compare Bigtable row-key columns against string literals in SQL","Keep non-string or NULL key comparisons in Beam-side filters","Match declared schema types for key columns to query literals"],"tags":["beam-sql","bigtable","filter-pushdown","null-literal"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}