{"record":{"id":"dd8c4c66f106934c","repo":"multica-ai/multica","slug":"identifier-q-has-more-than-one-dot-only-schema-t","errorCode":null,"errorMessage":"identifier %q has more than one dot; only schema.table is supported","messagePattern":"identifier %q has more than one dot; only schema\\.table is supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/migrate/main.go","lineNumber":475,"sourceCode":"}\n\n// quoteQualifiedIdentifier safely quotes either an unqualified table\n// name (\"foo\") or a schema-qualified name (\"schema.foo\") for embedding\n// into a SQL statement. Postgres does not let parametrized queries\n// supply identifiers, so we have to interpolate, but pgx.Identifier\n// does the right escaping (double-quotes, embedded-quote handling).\n//\n// The accepted shape is exactly one or two dot-separated components.\n// Names containing more than one dot are rejected outright rather than\n// silently sanitized into a \"schema\".\"b.c\" reference, which is valid\n// SQL but almost certainly not what the caller meant.\nfunc quoteQualifiedIdentifier(name string) (string, error) {\n\tif name == \"\" {\n\t\treturn \"\", fmt.Errorf(\"empty identifier\")\n\t}\n\tparts := strings.Split(name, \".\")\n\tif len(parts) > 2 {\n\t\treturn \"\", fmt.Errorf(\"identifier %q has more than one dot; only schema.table is supported\", name)\n\t}\n\tfor _, p := range parts {\n\t\tif p == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"empty component in %q\", name)\n\t\t}\n\t}\n\treturn pgx.Identifier(parts).Sanitize(), nil\n}\n","sourceCodeStart":457,"sourceCodeEnd":484,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/migrate/main.go#L457-L484","documentation":"quoteQualifiedIdentifier accepts exactly one or two dot-separated components (table or schema.table). Names with more than one dot are rejected outright instead of being silently sanitized into a legal-but-surprising \"schema\".\"b.c\" reference, which would point somewhere the caller did not intend.","triggerScenarios":"Passing a three-plus-part name such as \"db.schema.table\", a database-qualified Postgres name, or a value containing stray dots (e.g. a filename fragment or an untrimmed dotted string).","commonSituations":"Porting tooling from MySQL/SQLServer where db.schema.table is normal; pasting a fully-qualified name from a GUI client; a value built by joining config parts with \".\" and accidentally including an extra segment.","solutions":["Reduce the name to at most schema.table — drop the database/catalog component; in Postgres the database is chosen by connection, not by the identifier.","If the extra dot is a typo or stray join artifact, fix the construction of the string.","If you genuinely need dots inside an identifier, pass the pre-quoted form the function was designed to avoid — instead, quote each component yourself once and stop using this helper for that case."],"exampleFix":"// before\nq, err := quoteQualifiedIdentifier(\"mydb.public.issues\")\n\n// after\nq, err := quoteQualifiedIdentifier(\"public.issues\")","handlingStrategy":"validation","validationCode":"// Normalize before quoting: strip a leading database/catalog component\n// if your tooling conventionally carries one.\nfunc normalizeIdent(name string) string {\n    parts := strings.Split(name, \".\")\n    if len(parts) > 2 {\n        parts = parts[len(parts)-2:] // keep schema.table\n    }\n    return strings.Join(parts, \".\")\n}","typeGuard":"func isSupportedIdentifier(name string) bool {\n    parts := strings.Split(name, \".\")\n    return len(parts) <= 2\n}","tryCatchPattern":"q, err := quoteQualifiedIdentifier(name)\nif err != nil {\n    return fmt.Errorf(\"%q must be table or schema.table: %w\", name, err)\n}","preventionTips":["Standardize on schema.table in configs; the database is implied by the connection.","When porting MySQL/SQLServer tooling, add a normalization step that drops the catalog component.","Log the raw value in the error path — the %q in the message already shows it."],"tags":["go","validation","sql","identifiers","postgres"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}