MyCATApache/Mycat-Server · error · SQLSyntaxErrorException

op table not in schema

Error message

op table not in schema----{tablename}

What it means

routeToDDLNode cannot resolve the table named in the SQL to any schema/table configuration, so it cannot determine a target data node. MyCat logs 'table not in schema' and throws SQLSyntaxErrorException to reject statements against tables absent from schema.xml. This keeps routing from silently sending DML/DDL to a wrong or empty node set.

Solutions

  1. Add the missing table to schema.xml as a <table name="..." dataNode="..."/> entry and restart/reload MyCat config
  2. Set a default dataNode on the <schema> element so unconfigured tables route to a single node
  3. Correct the table name in the SQL or ensure the client connects to the intended schema

Example fix

// before (schema.xml)
<schema name="db" checkSQLschema="true">
  <table name="t_user" dataNode="dn1"/>
</schema>
// after
<schema name="db" checkSQLschema="true">
  <table name="t_user" dataNode="dn1"/>
  <table name="t_order" dataNode="dn1,dn2"/>
</schema>
Defensive patterns

Strategy: validation

Validate before calling

// before executing SQL
if (!schemaConfig.getTables().containsKey(tableName) && schemaConfig.getDataNode() == null) {
  throw new IllegalStateException("table " + tableName + " is not declared in schema.xml");
}

Try / catch

try { RouterUtil.routeToDDLNode(...); } catch (SQLSyntaxErrorException e) { // table missing in schema config
  LOGGER.error("configure the table in schema.xml", e); }

Prevention

When it happens

Trigger: Executing any SQL statement (via routeToDDLNode / routeNormalSqlWithDDLNode path) whose table name has no entry in schemaConfig.getTables() and where the schema has no default dataNode; also calling RouterUtil.routeToDDLNode directly with an unknown tableName.

Common situations: Typo in table name in the SQL; table exists in the database but was never declared as a <table> in schema.xml; client connects to the wrong logical schema; table name case mismatch between SQL and config.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/281afe7fd66e6c9b. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:258

					}  else if(isSlotFunction){
						nodes[i].setSlot(-1);
					}
					nodes[i].setStatement(rrsStmt);
				}
				rrs.setNodes(nodes);
			}
			rrs.setStatement(rrsStmt);
			return rrs;
		}else if(schema.getDataNode()!=null){		//默认节点ddl
			RouteResultsetNode[] nodes = new RouteResultsetNode[1];
			nodes[0] = new RouteResultsetNode(schema.getDataNode(), sqlType, stmt);
			nodes[0].setSource(rrs);
			rrs.setNodes(nodes);
			return rrs;
		}
		//both tablename and defaultnode null
		LOGGER.error("table not in schema----"+tablename);
		throw new SQLSyntaxErrorException("op table not in schema----"+tablename);
	}

	private  static String changeCreateTable(SchemaConfig schema,String tableName,String sql) {
		if (schema.getTables().containsKey(tableName)) {
			MySqlStatementParser parser = new MySqlStatementParser(sql);
			SQLStatement insertStatement = parser.parseStatement();
			if (insertStatement instanceof MySqlCreateTableStatement) {
				TableConfig tableConfig = schema.getTables().get(tableName);
				AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
				if (algorithm instanceof SlotFunction) {
					SQLColumnDefinition column = new SQLColumnDefinition();
					column.setDataType(new SQLCharacterDataType("int"));
					column.setName(new SQLIdentifierExpr("_slot"));
					column.setComment(new SQLCharExpr("自动迁移算法slot,禁止修改"));
					((SQLCreateTableStatement) insertStatement).getTableElementList().add(column);
					return insertStatement.toString();

				}

View on GitHub (pinned to 65f8d8beb7)