{"record":{"id":"4d01d28b64385c19","repo":"Tencent/WeKnora","slug":"failed-to-parse-sql-v","errorCode":null,"errorMessage":"failed to parse SQL: %v","messagePattern":"failed to parse SQL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/utils/inject.go","lineNumber":880,"sourceCode":"\t// Find validator config to check if tenant injection is enabled\n\tvalidator := &sqlValidator{\n\t\ttablesWithTenantID:  make(map[string]bool),\n\t\ttablesWithDeletedAt: make(map[string]bool),\n\t}\n\tfor _, opt := range opts {\n\t\topt(validator)\n\t}\n\n\t// If no SQL rewriting is enabled, return original SQL\n\tif !validator.enableTenantInjection && !validator.enableSoftDeleteInjection && !validator.enableHiddenKBFilter &&\n\t\t!validator.enableChunkEnabledFilter && !validator.enableSearchScopeFilter {\n\t\treturn sql, validationResult, nil\n\t}\n\n\t// Parse again to get normalized SQL\n\tresult, err := pg_query.Parse(sql)\n\tif err != nil {\n\t\treturn \"\", validationResult, fmt.Errorf(\"failed to parse SQL: %v\", err)\n\t}\n\n\t// Normalize SQL\n\tnormalizedSQL, err := pg_query.Deparse(result)\n\tif err != nil {\n\t\treturn \"\", validationResult, fmt.Errorf(\"failed to normalize SQL: %v\", err)\n\t}\n\n\t// Build table→alias map from parse tree (respects SQL aliases like \"kb\", \"k\")\n\ttablesInQuery := extractTableAliasMap(result)\n\n\t// Inject tenant conditions\n\tsecuredSQL := validator.injectTenantConditions(normalizedSQL, tablesInQuery)\n\t// Inject deleted_at IS NULL conditions\n\tsecuredSQL = validator.injectSoftDeleteConditions(securedSQL, tablesInQuery)\n\t// Inject hidden KB filter (exclude is_temporary = true knowledge bases)\n\tsecuredSQL = validator.injectHiddenKBFilter(securedSQL, tablesInQuery)\n\t// Exclude disabled chunks from model-visible query results.","sourceCodeStart":862,"sourceCodeEnd":898,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/inject.go#L862-L898","documentation":"After validation passes, ValidateAndSecureSQL re-parses the SQL with pg_query.Parse to obtain a parse tree for rewriting (tenant/soft-delete filter injection). If the PostgreSQL grammar parser rejects the SQL, this error wraps the parser message. It indicates the SQL string is not valid PostgreSQL syntax.","triggerScenarios":"SQL that passes the library's lightweight validation but cannot be parsed by the actual PostgreSQL parser via pg_query.Parse — e.g. dialect-specific syntax, malformed expressions, or SQL mutated between validation and this call.","commonSituations":"Using MySQL/SQLite-flavored syntax that PostgreSQL rejects; pg_query library version mismatch producing different grammar behavior; queries with placeholder/param syntax the parser does not accept.","solutions":["Read the wrapped pg_query error to find the syntax position and fix the SQL","Verify the query is valid PostgreSQL by running it (or EXPLAIN) against psql","Check the pg_query library version supports the SQL features used","Confirm the same string is passed to validation and rewrite (no mutation in between)"],"exampleFix":"// before\nq := \"SELECT * FROM knowledge_bases LIMIT ?\"\nsecured, _, err := utils.ValidateAndSecureSQL(q)\n// after\nq := \"SELECT * FROM knowledge_bases LIMIT $1\"\nsecured, _, err := utils.ValidateAndSecureSQL(q)","handlingStrategy":"validation","validationCode":"// Dry-run with the same parser before calling the library\nif _, err := pg_query.Parse(sql); err != nil {\n    return fmt.Errorf(\"invalid PostgreSQL syntax: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"secured, _, err := utils.ValidateAndSecureSQL(sql)\nif err != nil && strings.Contains(err.Error(), \"failed to parse SQL\") {\n    return fmt.Errorf(\"invalid PostgreSQL syntax: %w\", err)\n}","preventionTips":["Write PostgreSQL-dialect SQL only (use $1 placeholders, not ?)","Keep the pg_query-go dependency up to date","Test generated queries against a real PostgreSQL instance in CI","Never mutate the SQL string between construction and validation"],"tags":["sql","postgres","parsing"],"backgroundTag":"sql-parse-error","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}