{"record":{"id":"f268fe65c7d147f7","repo":"prestodb/presto","slug":"sample-percentage-out-of-range","errorCode":"SAMPLE_PERCENTAGE_OUT_OF_RANGE","errorMessage":"Sample percentage must be greater than or equal to 0","messagePattern":"Sample percentage must be greater than or equal to 0","errorType":"error_code","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java","lineNumber":3203,"sourceCode":"\n            Object samplePercentageObject = samplePercentageEval.optimize(symbol -> {\n                throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), \"Sample percentage cannot contain column references\");\n            });\n            try {\n                samplePercentageObject = evaluateConstantExpression(relation.getSamplePercentage(), DOUBLE, metadata, session,\n                        analysis.getParameters());\n            }\n            catch (SemanticException e) {\n                if (e.getCode() == TYPE_MISMATCH) {\n                    throw new SemanticException(NON_NUMERIC_SAMPLE_PERCENTAGE, relation.getSamplePercentage(), \"Sample percentage should evaluate to a double\");\n                }\n                throw e;\n            }\n\n            double samplePercentageValue = (Double) samplePercentageObject;\n\n            if (samplePercentageValue < 0.0) {\n                throw new SemanticException(SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE, relation.getSamplePercentage(), \"Sample percentage must be greater than or equal to 0\");\n            }\n            if ((samplePercentageValue > 100.0)) {\n                throw new SemanticException(SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE, relation.getSamplePercentage(), \"Sample percentage must be less than or equal to 100\");\n            }\n\n            analysis.setSampleRatio(relation, samplePercentageValue / 100);\n            Scope relationScope = process(relation.getRelation(), scope);\n\n            // TABLESAMPLE cannot be applied to a polymorphic table function (SQL standard ISO/IEC 9075-2, 7.6 <table reference>, p. 409)\n            // Note: the below method finds a table function immediately nested in SampledRelation, or aliased.\n            // Potentially, a table function could be also nested with intervening PatternRecognitionRelation.\n            // Such case is handled in visitPatternRecognitionRelation().\n            validateNoNestedTableFunction(relation.getRelation(), \"sample\");\n\n            return createAndAssignScope(relation, scope, relationScope.getRelationType());\n        }\n\n        // this method should run after the `base` relation is processed, so that it is","sourceCodeStart":3185,"sourceCodeEnd":3221,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java#L3185-L3221","documentation":"Once the sample percentage evaluates to a double, Presto validates its range: values below 0 are rejected with SAMPLE_PERCENTAGE_OUT_OF_RANGE because a negative sample fraction is meaningless. Valid percentages are 0 through 100 inclusive.","triggerScenarios":"SELECT * FROM t TABLESAMPLE BERNOULLI (-5); a computed constant expression folding to a negative number; a query template where a variable is substituted with a negative value.","commonSituations":"Off-by-sign bugs in generated SQL; parameterized sampling where a caller passes negative rates; misconfigured sampling jobs writing bad percentages into query templates.","solutions":["Clamp the percentage to [0, 100] before generating the query","Validate the sampling configuration value before substitution","Use 0 to express 'no rows' rather than a negative value"],"exampleFix":"// before\ndouble pct = config.getSamplePct(); // could be -5\n// after\ndouble pct = Math.max(0.0, Math.min(100.0, config.getSamplePct()));","handlingStrategy":"validation","validationCode":"double pct = resolveSamplePercentage(config);\nif (pct < 0.0) {\n    throw new IllegalArgumentException(\"sample percentage must be >= 0, got \" + pct);\n}","typeGuard":"boolean isValidSamplePct(double pct) { return pct >= 0.0 && pct <= 100.0; }","tryCatchPattern":"try {\n    return engine.execute(sql);\n} catch (SemanticException e) {\n    if (e.getCode() == SemanticErrorCode.SAMPLE_PERCENTAGE_OUT_OF_RANGE) {\n        sql = clampSamplePct(sql, 0.0, 100.0); // clamp and retry once\n    } else { throw e; }\n}","preventionTips":["Clamp sample rates to [0, 100] in configuration loading code","Reject negative sampling config at job-submission time","Log and sanitize values substituted into TABLESAMPLE templates","Treat 0 as the explicit 'sample nothing' value"],"tags":["presto","sql","tablesample","range-validation"],"backgroundTag":"sample-percentage-out-of-range","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"}