{"record":{"id":"e9872ab7aa950c9d","repo":"MyCATApache/Mycat-Server","slug":"namesuffix-tablenamesuffixelement-require-name","errorCode":null,"errorMessage":"nameSuffix ${tableNameSuffixElement}, require name parameter cannot multiple breaks!","messagePattern":"nameSuffix (.+?), require name parameter cannot multiple breaks!","errorType":"exception","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java","lineNumber":331,"sourceCode":"            }else {\n                list.add(tableElement);\n            }\n        }\n        loadTable(schemaName, tables, list);\n        return tables;\n    }\n\n    private void loadTable(String schemaName, Map<String, TableConfig> tables,  List<Element>  nodeList) {\n        for (int i = 0; i < nodeList.size(); i++) {\n            Element tableElement = (Element) nodeList.get(i);\n            String tableNameElement = tableElement.getAttribute(\"name\").toUpperCase();\n\n            //TODO:路由, 增加对动态日期表的支持\n            String tableNameSuffixElement = tableElement.getAttribute(\"nameSuffix\").toUpperCase();\n            if (!\"\".equals(tableNameSuffixElement)) {\n\n                if (tableNameElement.split(\",\").length > 1) {\n                    throw new ConfigException(\"nameSuffix \" + tableNameSuffixElement + \", require name parameter cannot multiple breaks!\");\n                }\n                //前缀用来标明日期格式\n                tableNameElement = doTableNameSuffix(tableNameElement, tableNameSuffixElement);\n            }\n            //记录主键，用于之后路由分析，以及启用自增长主键\n            String[] tableNames = tableNameElement.split(\",\");\n            String primaryKey = tableElement.hasAttribute(\"primaryKey\") ? tableElement.getAttribute(\"primaryKey\").toUpperCase() : null;\n            //记录是否主键自增，默认不是，（启用全局sequence handler）\n            boolean autoIncrement = false;\n            if (tableElement.hasAttribute(\"autoIncrement\")) {\n                autoIncrement = Boolean.parseBoolean(tableElement.getAttribute(\"autoIncrement\"));\n            }\n\n            boolean fetchStoreNodeByJdbc = false;\n            if (tableElement.hasAttribute(\"fetchStoreNodeByJdbc\")) {\n                fetchStoreNodeByJdbc = Boolean.parseBoolean(tableElement.getAttribute(\"fetchStoreNodeByJdbc\"));\n            }\n            //记录是否需要加返回结果集限制，默认需要加","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java#L313-L349","documentation":"loadTable supports dynamic date-suffix table names via the nameSuffix attribute, but this feature works only for a single logical table. If the name attribute lists multiple comma-separated tables while nameSuffix is set, loadTable throws this ConfigException because the suffix expansion cannot be applied unambiguously to multiple names.","triggerScenarios":"schema.xml table element like <table name=\"t1,t2\" nameSuffix=\"_202401\" ...>; loadTable -> loadTables sees tableNameElement.split(\",\").length > 1 when nameSuffix is non-empty and throws.","commonSituations":"Bulk-declaring several date-partitioned tables in one line assuming multi-name support; copying a multi-table config line and adding nameSuffix for dynamic tables; misunderstanding that nameSuffix applies per table only.","solutions":["Split the comma-separated name attribute into separate <table> entries, each with its own nameSuffix.","If the tables are not actually date-partitioned, remove the nameSuffix attribute so the multi-name list is allowed.","Restart and confirm the schema loads."],"exampleFix":"// before (schema.xml)\n<table name=\"order,order_log\" dataNode=\"dn1\" nameSuffix=\"_202401\" />\n// after\n<table name=\"order\" dataNode=\"dn1\" nameSuffix=\"_202401\" />\n<table name=\"order_log\" dataNode=\"dn1\" nameSuffix=\"_202401\" />","handlingStrategy":"validation","validationCode":"// nameSuffix cannot be combined with multi-name tables\nNodeList tables = doc.getElementsByTagName(\"table\");\nfor (int i = 0; i < tables.getLength(); i++) {\n    Element t = (Element) tables.item(i);\n    String suffix = t.getAttribute(\"nameSuffix\");\n    if (!suffix.isEmpty() && t.getAttribute(\"name\").contains(\",\"))\n        throw new IllegalStateException(\"nameSuffix table must declare a single name: \" + t.getAttribute(\"name\"));\n}","typeGuard":null,"tryCatchPattern":"try {\n    loader = new XMLSchemaLoader();\n} catch (ConfigException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"nameSuffix\")) {\n        LOG.error(\"nameSuffix requires single table name: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Use one <table> element per dynamically-suffixed table.","Only add nameSuffix when you actually need date-based dynamic tables.","Lint schema.xml: flag any table element with both a comma in name and a nameSuffix attribute."],"tags":["configuration","xml","mutually-exclusive","sharding"],"backgroundTag":"conflicting-config-options","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}