{"record":{"id":"eeb4a7c8e3be4326","repo":"prestodb/presto","slug":"invalid-arguments-eeb4a7","errorCode":"INVALID_ARGUMENTS","errorMessage":"Table version AS OF/BEFORE expression cannot be NULL for %s","messagePattern":"Table version AS OF/BEFORE expression cannot be NULL for (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java","lineNumber":2587,"sourceCode":"            switch (type) {\n                case TIMESTAMP:\n                    return VersionType.TIMESTAMP;\n                case VERSION:\n                    return VersionType.VERSION;\n            }\n            throw new SemanticException(NOT_SUPPORTED, \"Table version type %s not supported.\" + type);\n        }\n\n        private Optional<TableHandle> processTableVersion(Table table, QualifiedObjectName name, Optional<Scope> scope)\n        {\n            Expression stateExpr = table.getTableVersionExpression().get().getStateExpression();\n            TableVersionType tableVersionType = table.getTableVersionExpression().get().getTableVersionType();\n            TableVersionOperator tableVersionOperator = table.getTableVersionExpression().get().getTableVersionOperator();\n            ExpressionAnalysis expressionAnalysis = analyzeExpression(stateExpr, scope.get());\n            analysis.recordSubqueries(table, expressionAnalysis);\n            Type stateExprType = expressionAnalysis.getType(stateExpr);\n            if (stateExprType == UNKNOWN) {\n                throw new PrestoException(StandardErrorCode.INVALID_ARGUMENTS, format(\"Table version AS OF/BEFORE expression cannot be NULL for %s\", name.toString()));\n            }\n            Object evalStateExpr = evaluateConstantExpression(stateExpr, stateExprType, metadata, session, analysis.getParameters());\n            if (tableVersionType == TIMESTAMP) {\n                if (!(stateExprType instanceof TimestampWithTimeZoneType || stateExprType instanceof TimestampType\n                        || stateExprType instanceof BigintType || stateExprType instanceof VarcharType)) {\n                    throw new SemanticException(TYPE_MISMATCH, stateExpr,\n                            \"Type %s is invalid. Supported table version AS OF/BEFORE expression type is Timestamp, Timestamp with Time Zone, BIGINT, or VARCHAR.\",\n                            stateExprType.getDisplayName());\n                }\n            }\n            if (tableVersionType == VERSION) {\n                if (!(stateExprType instanceof BigintType || stateExprType instanceof VarcharType)) {\n                    throw new SemanticException(TYPE_MISMATCH, stateExpr,\n                            \"Type %s is invalid. Supported table version AS OF/BEFORE expression type is BIGINT or VARCHAR\",\n                            stateExprType.getDisplayName());\n                }\n            }\n","sourceCodeStart":2569,"sourceCodeEnd":2605,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java#L2569-L2605","documentation":"The expression in a FOR TIMESTAMP/VERSION AS OF/BEFORE clause must evaluate to a known (non-NULL) constant. After analyzing the state expression, if its type is UNKNOWN (e.g. a NULL literal), Presto throws INVALID_ARGUMENTS because a NULL version or timestamp cannot identify a table snapshot.","triggerScenarios":"SELECT * FROM t FOR TIMESTAMP AS OF NULL; or an expression that folds to NULL/UNKNOWN type (e.g. a constant-folding NULL parameter). Detected by stateExprType == UNKNOWN right after analyzeExpression.","commonSituations":"Passing NULL via a session parameter used in AS OF clauses; template-generated SQL with an unset timestamp placeholder; copy-paste queries with placeholder values not filled in.","solutions":["Provide a concrete non-NULL timestamp or version value in the AS OF/BEFORE clause","Substitute any session/prepare parameters with actual values before running the query","If the value may be missing at runtime, branch in application code and only include the FOR clause when a valid value exists"],"exampleFix":"// before\nSELECT * FROM t FOR TIMESTAMP AS OF ?; -- parameter bound to NULL\n// after\nSELECT * FROM t FOR TIMESTAMP AS OF TIMESTAMP '2024-01-01 00:00:00';","handlingStrategy":"validation","validationCode":"if (versionValue == null) {\n    throw new IllegalArgumentException(\"AS OF/BEFORE value must be non-NULL\");\n}","typeGuard":"function hasVersionValue(v) {\n    return v !== null && v !== undefined;\n}","tryCatchPattern":"try {\n    return session.execute(query);\n} catch (PrestoException e) {\n    if (e.getStandardErrorCode() == INVALID_ARGUMENTS) {\n        // substitute a concrete timestamp/version and retry\n    }\n    throw e;\n}","preventionTips":["Bind real values, never NULL, into AS OF/BEFORE parameters","Guard template-generated SQL so the FOR clause is omitted when the value is missing","Validate placeholders are filled before executing snapshot queries"],"tags":["sql","time-travel","null-value","invalid-arguments"],"backgroundTag":"invalid-argument-null","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}