diff --git a/dialect/api/src/main/java/org/eclipse/daanse/sql/dialect/api/generator/DdlGenerator.java b/dialect/api/src/main/java/org/eclipse/daanse/sql/dialect/api/generator/DdlGenerator.java index d5598bc..4a20f4e 100644 --- a/dialect/api/src/main/java/org/eclipse/daanse/sql/dialect/api/generator/DdlGenerator.java +++ b/dialect/api/src/main/java/org/eclipse/daanse/sql/dialect/api/generator/DdlGenerator.java @@ -602,7 +602,7 @@ default String createTrigger(String triggerName, Trigger.TriggerTiming timing, T if (orReplace && supportsCreateOrReplaceTrigger()) sb.append("OR REPLACE "); sb.append("TRIGGER "); - sb.append(quoteIdentifier(triggerName)); + sb.append(triggerName(triggerName, table)); sb.append(' ').append(triggerTimingKeyword(timing)).append(' ').append(event); sb.append(" ON ").append(qualified(table)); sb.append(' ').append(scope.forEachClause()); @@ -613,6 +613,14 @@ default String createTrigger(String triggerName, Trigger.TriggerTiming timing, T return sb.toString(); } + /** + * How a trigger name is written. Unqualified by default; a dialect that + * scopes a trigger to its table's schema has to say so in the name. + */ + default String triggerName(String triggerName, TableReference table) { + return quoteIdentifier(triggerName); + } + default Optional createTriggerProcedure(String procedureName, String schemaName, String body) { return Optional.empty(); } diff --git a/dialect/db/mysql/src/main/java/org/eclipse/daanse/sql/dialect/db/mysql/MySqlDialect.java b/dialect/db/mysql/src/main/java/org/eclipse/daanse/sql/dialect/db/mysql/MySqlDialect.java index 0504714..2a354d8 100644 --- a/dialect/db/mysql/src/main/java/org/eclipse/daanse/sql/dialect/db/mysql/MySqlDialect.java +++ b/dialect/db/mysql/src/main/java/org/eclipse/daanse/sql/dialect/db/mysql/MySqlDialect.java @@ -569,6 +569,17 @@ public String createTriggerUsingProcedure(String triggerName, String schemaName, return createTrigger(triggerName, timing, event, table, scope, whenCondition, "CALL " + qualified + "()"); } + /** + * MySQL and MariaDB scope a trigger to its table's schema, and the name has + * to say so. Left unqualified the server creates it in the session's current + * database and then refuses it: Trigger in wrong schema. + */ + @Override + public String triggerName(String triggerName, org.eclipse.daanse.sql.model.schema.TableReference table) { + return table == null || table.schema().isEmpty() ? quoteIdentifier(triggerName) + : quoteIdentifier(table.schema().get().name(), triggerName); + } + /** MySQL/MariaDB: {@code DROP PROCEDURE [IF EXISTS] schema.procedureName}. */ @Override public Optional dropProcedure(String procedureName, String schemaName, boolean ifExists) { diff --git a/jdbc/impl/src/main/java/org/eclipse/daanse/sql/jdbc/impl/DatabaseServiceImpl.java b/jdbc/impl/src/main/java/org/eclipse/daanse/sql/jdbc/impl/DatabaseServiceImpl.java index c54accd..f7f3931 100644 --- a/jdbc/impl/src/main/java/org/eclipse/daanse/sql/jdbc/impl/DatabaseServiceImpl.java +++ b/jdbc/impl/src/main/java/org/eclipse/daanse/sql/jdbc/impl/DatabaseServiceImpl.java @@ -369,6 +369,18 @@ protected StructureInfo getStructureInfo(DatabaseMetaData databaseMetaData) thro return structureInfo; } + /** + * The namespace a relation lives in. A driver that reports no schema keeps + * it in the catalog - MySQL and MariaDB call it a database - so the catalog + * name stands in. Without that a consumer grouping relations by schema + * loses every one of them on those servers. + */ + private static Optional namespaceOf(Optional catalogName, Optional schemaName) { + Optional catalog = catalogName.map(CatalogReference::new); + return schemaName.map(sn -> new SchemaReference(catalog, sn)) + .or(() -> catalogName.map(cn -> new SchemaReference(Optional.empty(), cn))); + } + private List getCatalogs(DatabaseMetaData databaseMetaData) throws SQLException { List catalogs = new ArrayList<>(); @@ -500,7 +512,7 @@ private List getTableDefinitions(DatabaseMetaData databaseMetaD final Optional oRefGen = getColumnValue(rs, columnNames, "REF_GENERATION"); Optional oCatRef = oCatalogName.map(cn -> new CatalogReference(cn)); - Optional oSchemaRef = oSchemaName.map(sn -> new SchemaReference(oCatRef, sn)); + Optional oSchemaRef = namespaceOf(oCatalogName, oSchemaName); TableReference tableReference = new TableReference(oSchemaRef, tableName, tableType); TableMetaData tableMetaData = new TableMetaDataRecord(oRemarks, oTypeCat, oTypeSchema, oTypeName, @@ -730,7 +742,7 @@ private List getColumnDefinitions(DatabaseMetaData databaseMet } Optional oCatRef = oCatalogName.map(cn -> new CatalogReference(cn)); - Optional oSchemaRef = oSchemaName.map(sn -> new SchemaReference(oCatRef, sn)); + Optional oSchemaRef = namespaceOf(oCatalogName, oSchemaName); JDBCType jdbcType; try { @@ -811,13 +823,13 @@ private List getImportedKeys(DatabaseMetaData databaseMetaData, Str // PK Optional oCatRefPk = oCatalogNamePK.map(cn -> new CatalogReference(cn)); - Optional oSchemaRefPk = oSchemaNamePk.map(sn -> new SchemaReference(oCatRefPk, sn)); + Optional oSchemaRefPk = namespaceOf(oCatalogNamePK, oSchemaNamePk); TableReference tableReferencePk = new TableReference(oSchemaRefPk, tableNamePk); ColumnReference primaryKeyColumn = new ColumnReference(Optional.of(tableReferencePk), columNamePk); // FK Optional oCatRefFk = oCatalogNameFK.map(cn -> new CatalogReference(cn)); - Optional oSchemaRefFk = oSchemaNameFk.map(sn -> new SchemaReference(oCatRefFk, sn)); + Optional oSchemaRefFk = namespaceOf(oCatalogNameFK, oSchemaNameFk); TableReference tableReferenceFk = new TableReference(oSchemaRefFk, tableNameFk); ColumnReference foreignKeyColumn = new ColumnReference(Optional.of(tableReferenceFk), columNameFk); @@ -927,7 +939,7 @@ private List getProcedures(DatabaseMetaData databaseMetaData, String final String specificName = rs.getString("SPECIFIC_NAME"); Optional oCatRef = oCatalogName.map(CatalogReference::new); - Optional oSchemaRef = oSchemaName.map(sn -> new SchemaReference(oCatRef, sn)); + Optional oSchemaRef = namespaceOf(oCatalogName, oSchemaName); ProcedureReference reference = new ProcedureReference(oSchemaRef, procedureName, specificName); @@ -1012,7 +1024,7 @@ private List getFunctions(DatabaseMetaData databaseMetaData, String ca final String specificName = rs.getString("SPECIFIC_NAME"); Optional oCatRef = oCatalogName.map(CatalogReference::new); - Optional oSchemaRef = oSchemaName.map(sn -> new SchemaReference(oCatRef, sn)); + Optional oSchemaRef = namespaceOf(oCatalogName, oSchemaName); FunctionReference reference = new FunctionReference(oSchemaRef, functionName, specificName); @@ -1157,13 +1169,13 @@ private ImportedKey readForeignKeyFromResultSet(ResultSet rs) throws SQLExceptio // PK Optional oCatRefPk = oCatalogNamePK.map(CatalogReference::new); - Optional oSchemaRefPk = oSchemaNamePk.map(sn -> new SchemaReference(oCatRefPk, sn)); + Optional oSchemaRefPk = namespaceOf(oCatalogNamePK, oSchemaNamePk); TableReference tableReferencePk = new TableReference(oSchemaRefPk, tableNamePk); ColumnReference primaryKeyColumn = new ColumnReference(Optional.of(tableReferencePk), columNamePk); // FK Optional oCatRefFk = oCatalogNameFK.map(CatalogReference::new); - Optional oSchemaRefFk = oSchemaNameFk.map(sn -> new SchemaReference(oCatRefFk, sn)); + Optional oSchemaRefFk = namespaceOf(oCatalogNameFK, oSchemaNameFk); TableReference tableReferenceFk = new TableReference(oSchemaRefFk, tableNameFk); ColumnReference foreignKeyColumn = new ColumnReference(Optional.of(tableReferenceFk), columNameFk); @@ -1208,7 +1220,7 @@ private List getUDTs(DatabaseMetaData databaseMetaData, String jdbcType = JDBCType.OTHER; } Optional catRef = oCat.map(CatalogReference::new); - Optional schemaRef = oSchema.map(sn -> new SchemaReference(catRef, sn)); + Optional schemaRef = namespaceOf(oCat, oSchema); result.add(new UserDefinedTypeRecord( new UserDefinedTypeReference(schemaRef, typeName), className, jdbcType, remarks)); @@ -1297,7 +1309,7 @@ private List getPseudoColumns(DatabaseMetaData databaseMetaData, S String columnUsage = rs.getString("COLUMN_USAGE"); Optional catRef = oCat.map(CatalogReference::new); - Optional schemaRef = oSchema.map(sn -> new SchemaReference(catRef, sn)); + Optional schemaRef = namespaceOf(oCat, oSchema); TableReference tableRef = new TableReference(schemaRef, tableName); ColumnReference colRef = new ColumnReference(Optional.of(tableRef), columnName); @@ -1322,7 +1334,7 @@ private List getTablePrivileges(DatabaseMetaData databaseMetaDat Optional isGrantable = Optional.ofNullable(rs.getString("IS_GRANTABLE")); Optional catRef = oCat.map(CatalogReference::new); - Optional schemaRef = oSchema.map(sn -> new SchemaReference(catRef, sn)); + Optional schemaRef = namespaceOf(oCat, oSchema); TableReference tableRef = new TableReference(schemaRef, tableName); result.add(new TablePrivilegeRecord(tableRef, grantor, grantee, privilege, isGrantable)); @@ -1388,7 +1400,7 @@ private List getSuperTables(DatabaseMetaData databaseMetaData, Strin String superTableName = rs.getString("SUPERTABLE_NAME"); Optional catRef = oCat.map(CatalogReference::new); - Optional schemaRef = oSchema.map(sn -> new SchemaReference(catRef, sn)); + Optional schemaRef = namespaceOf(oCat, oSchema); TableReference tableRef = new TableReference(schemaRef, tableName); result.add(new SuperTableRecord(tableRef, superTableName));