This is an automated email from the ASF dual-hosted git repository. amashenkov pushed a commit to branch ignite-18535 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit e27bea7cec0426b62bf3f892b3088f2bc11d0aa0 Author: amashenkov <[email protected]> AuthorDate: Thu Mar 16 00:04:04 2023 +0300 WIP. Add descriptor classes for catalog's objects and CatalogService stub. --- modules/catalog/README.md | 7 ++ modules/catalog/build.gradle | 36 +++++++ .../ignite/internal/catalog/CatalogService.java | 52 +++++++++++ .../internal/catalog/CatalogServiceImpl.java | 103 +++++++++++++++++++++ .../catalog/descriptors/CatalogDescriptor.java | 100 ++++++++++++++++++++ .../catalog/descriptors/ColumnCollation.java | 73 +++++++++++++++ .../catalog/descriptors/HashIndexDescriptor.java | 64 +++++++++++++ .../catalog/descriptors/IndexColumnDescriptor.java | 52 +++++++++++ .../catalog/descriptors/IndexDescriptor.java | 60 ++++++++++++ .../catalog/descriptors/ObjectDescriptor.java | 62 +++++++++++++ .../catalog/descriptors/SchemaDescriptor.java | 90 ++++++++++++++++++ .../catalog/descriptors/SortedIndexDescriptor.java | 59 ++++++++++++ .../catalog/descriptors/TableColumnDescriptor.java | 75 +++++++++++++++ .../catalog/descriptors/TableDescriptor.java | 86 +++++++++++++++++ .../internal/catalog/events/CatalogEvent.java | 26 ++++++ .../catalog/events/CatalogEventParameters.java | 34 +++++++ settings.gradle | 2 + 17 files changed, 981 insertions(+) diff --git a/modules/catalog/README.md b/modules/catalog/README.md new file mode 100644 index 0000000000..e21ccad796 --- /dev/null +++ b/modules/catalog/README.md @@ -0,0 +1,7 @@ +# Catalog module + +This module provides database catalog service implementation and descriptor for catalog objects. + +See [CatalogService](src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java) + +TODO: IGNITE-18535 Add comprehensive description. \ No newline at end of file diff --git a/modules/catalog/build.gradle b/modules/catalog/build.gradle new file mode 100644 index 0000000000..a126476f48 --- /dev/null +++ b/modules/catalog/build.gradle @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +apply from: "$rootDir/buildscripts/java-core.gradle" +apply from: "$rootDir/buildscripts/publishing.gradle" +apply from: "$rootDir/buildscripts/java-junit5.gradle" + +dependencies { + annotationProcessor project(':ignite-configuration-annotation-processor') + annotationProcessor libs.auto.service + implementation libs.jetbrains.annotations + + implementation project(':ignite-api') + implementation project(':ignite-core') + implementation project(':ignite-configuration') + implementation libs.jetbrains.annotations + + testImplementation(testFixtures(project(':ignite-configuration'))) + testImplementation(testFixtures(project(':ignite-core'))) +} + +description = "ignite-catalog" diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogService.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogService.java new file mode 100644 index 0000000000..0767cbde36 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogService.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog; + +import java.util.Collection; +import java.util.concurrent.CompletableFuture; +import org.apache.ignite.internal.catalog.descriptors.IndexDescriptor; +import org.apache.ignite.internal.catalog.descriptors.SchemaDescriptor; +import org.apache.ignite.internal.catalog.descriptors.TableDescriptor; +import org.apache.ignite.internal.configuration.DynamicConfigurationChanger; + +/** + * Catalog service provides methods to access schema object's descriptors of exact version and/or last actual version at given timestamp, + * which is logical point-in-time. + * + * <p>Catalog service is responsible for proper configuration updates and storing/restoring schema evolution history (schema versions) + * for time-travelled queries purposes and lazy data evolution purposes. + * + * <p>TBD: schema manipulation methods. + * TBD: events + */ +public interface CatalogService { + TableDescriptor table(String tableName, long timestamp); + + TableDescriptor table(int tableId, long timestamp); + + IndexDescriptor index(int indexId, long timestamp); + + Collection<IndexDescriptor> tableIndexes(int tableId, long timestamp); + + SchemaDescriptor schema(int version); + + SchemaDescriptor activeSchema(long timestamp); + + //TODO: IGNITE-18535 enrich with schema manipulation methods. + CompletableFuture<SchemaDescriptor> updateSchema(DynamicConfigurationChanger changer); +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java new file mode 100644 index 0000000000..e46d1bc788 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/CatalogServiceImpl.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog; + +import java.util.Collection; +import java.util.Map.Entry; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentNavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; +import org.apache.ignite.internal.catalog.descriptors.CatalogDescriptor; +import org.apache.ignite.internal.catalog.descriptors.IndexDescriptor; +import org.apache.ignite.internal.catalog.descriptors.SchemaDescriptor; +import org.apache.ignite.internal.catalog.descriptors.TableDescriptor; +import org.apache.ignite.internal.catalog.events.CatalogEvent; +import org.apache.ignite.internal.catalog.events.CatalogEventParameters; +import org.apache.ignite.internal.configuration.DynamicConfigurationChanger; +import org.apache.ignite.internal.manager.Producer; +import org.jetbrains.annotations.Nullable; + +/** + * TODO: IGNITE-18535 Fix javadoc + */ +public class CatalogServiceImpl extends Producer<CatalogEvent, CatalogEventParameters> implements CatalogService { + + /** Versioned catalog descriptors. */ + private final ConcurrentMap<Integer, CatalogDescriptor> catalogByVer = new ConcurrentHashMap<>(); //TODO: IGNITE-18535 Use IntMap instead. + + /** Versioned catalog descriptors sorted in chronological order. */ + private final ConcurrentNavigableMap<Long, CatalogDescriptor> catalogByTs = new ConcurrentSkipListMap<>(); //TODO: IGNITE-18535 Use LongMap instead. + + /** {@inheritDoc} */ + @Override + public TableDescriptor table(String tableName, long timestamp) { + return catalogAt(timestamp).schema(CatalogDescriptor.DEFAULT_SCHEMA_NAME).table(tableName); + } + + /** {@inheritDoc} */ + @Override + public TableDescriptor table(int tableId, long timestamp) { + return catalogAt(timestamp).table(tableId); + } + + /** {@inheritDoc} */ + @Override + public IndexDescriptor index(int indexId, long timestamp) { + return catalogAt(timestamp).index(indexId); + } + + /** {@inheritDoc} */ + @Override + public Collection<IndexDescriptor> tableIndexes(int tableId, long timestamp) { + return catalogAt(timestamp).tableIndexes(tableId); + } + + /** {@inheritDoc} */ + @Override + public SchemaDescriptor schema(int version) { + return catalog(version).schema(CatalogDescriptor.DEFAULT_SCHEMA_NAME); + } + + /** {@inheritDoc} */ + @Override + public @Nullable SchemaDescriptor activeSchema(long timestamp) { + return catalogAt(timestamp).schema(CatalogDescriptor.DEFAULT_SCHEMA_NAME); + } + + /** {@inheritDoc} */ + @Override + public CompletableFuture<SchemaDescriptor> updateSchema(DynamicConfigurationChanger changer) { + return null; + } + + private CatalogDescriptor catalog(int version) { + return catalogByVer.get(version); + } + + private CatalogDescriptor catalogAt(long timestamp) { + Entry<Long, CatalogDescriptor> entry = catalogByTs.floorEntry(timestamp); + + if (entry == null) { + throw new IllegalStateException("No valid schema found for given timestamp: " + timestamp); + } + + return entry.getValue(); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogDescriptor.java new file mode 100644 index 0000000000..9f5ba39ae3 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/CatalogDescriptor.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.apache.ignite.internal.tostring.IgniteToStringExclude; +import org.apache.ignite.internal.tostring.S; + +/** + * Catalog descriptor represents database schema snapshot. + */ +public class CatalogDescriptor implements Serializable { + public static final String DEFAULT_SCHEMA_NAME = "PUBLIC"; + private static final long serialVersionUID = -2713639412596667759L; + private final int version; + private final long activationTimestamp; + private final Map<String, SchemaDescriptor> schemas; + + @IgniteToStringExclude + private transient Map<Integer, TableDescriptor> tablesMap; + @IgniteToStringExclude + private transient Map<Integer, IndexDescriptor> indexesMap; + + + public CatalogDescriptor(int version, long activationTimestamp, SchemaDescriptor[] descriptors) { + this.version = version; + this.activationTimestamp = activationTimestamp; + + Objects.requireNonNull(descriptors, "schemas"); + + assert descriptors.length > 0 : "No schemas found"; + assert Arrays.stream(descriptors).allMatch(t -> t.version() == version) : "Invalid schema version"; + + schemas = Arrays.stream(descriptors).collect(Collectors.toUnmodifiableMap(SchemaDescriptor::name, t -> t)); + + rebuildMaps(); + } + + public long time() { + return activationTimestamp; + } + + public SchemaDescriptor schema(String name) { + return schemas.get(name); + } + + public TableDescriptor table(int tableId) { + return tablesMap.get(tableId); + } + + public IndexDescriptor index(int indexId) { + return indexesMap.get(indexId); + } + + public Collection<IndexDescriptor> tableIndexes(int tableId) { + return indexesMap.values().stream().filter(desc -> desc.tableId() == tableId).collect(Collectors.toList()); + } + + private void rebuildMaps() { + tablesMap = schemas.values().stream().flatMap(s -> Arrays.stream(s.tables())) + .collect(Collectors.toUnmodifiableMap(ObjectDescriptor::id, Function.identity())); + indexesMap = schemas.values().stream().flatMap(s -> Arrays.stream(s.indexes())). + collect(Collectors.toUnmodifiableMap(ObjectDescriptor::id, Function.identity())); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + rebuildMaps(); + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/ColumnCollation.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/ColumnCollation.java new file mode 100644 index 0000000000..1acb243625 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/ColumnCollation.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +/** + * Enumeration of all supported collations. + */ +//TODO: IGNITE-18535 drop similar classes in index and sql-engine modules. +public enum ColumnCollation { + ASC_NULLS_FIRST(true, true), + ASC_NULLS_LAST(true, false), + DESC_NULLS_FIRST(false, true), + DESC_NULLS_LAST(false, false); + + + private final boolean asc; + private final boolean nullsFirst; + + /** + * Constructs the collation object. + * + * @param asc Direction of the sorting. + * @param nullsFirst Place of the null values in sorted range. + */ + ColumnCollation(boolean asc, boolean nullsFirst) { + this.asc = asc; + this.nullsFirst = nullsFirst; + } + + /** + * Returns collation object for given directions. + * + * @param asc Whether the values should be sorted in ascending order. + * @param nullsFirst Whether to put null values first. + * @return A collation object. + */ + public static ColumnCollation get(boolean asc, boolean nullsFirst) { + if (asc && nullsFirst) { + return ASC_NULLS_FIRST; + } else if (asc) { + return ASC_NULLS_LAST; + } else if (nullsFirst) { + return DESC_NULLS_FIRST; + } else { + return DESC_NULLS_LAST; + } + } + + /** Returns whether the column sorted in ascending order. */ + public boolean asc() { + return asc; + } + + /** Returns whether null values should be in the very beginning of the range. */ + public boolean nullsFirst() { + return nullsFirst; + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/HashIndexDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/HashIndexDescriptor.java new file mode 100644 index 0000000000..8e2d96c3da --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/HashIndexDescriptor.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import org.apache.ignite.internal.tostring.S; + +/** + * Hash index descriptor. + */ +public class HashIndexDescriptor extends IndexDescriptor { + private static final long serialVersionUID = -6784028115063219759L; + + private final List<String> columns; + + /** + * Constructs a hash index descriptor. + * + * @param id Id of the index. + * @param name Name of the index. + * @param tableId Id of the table index belongs to. + * @param columns A list of indexed columns. Must not contains duplicates. + * @throws IllegalArgumentException If columns list contains duplicates. + */ + public HashIndexDescriptor(int id, String name, int tableId, List<String> columns) { + super(id, name, tableId, true); + + this.columns = List.copyOf(Objects.requireNonNull(columns, "columns")); + + if (new HashSet<>(columns).size() != columns.size()) { + throw new IllegalArgumentException("Indexed columns should be unique"); + } + } + + /** Returns indexed columns. */ + public List<String> columns() { + return columns; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} + + diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/IndexColumnDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/IndexColumnDescriptor.java new file mode 100644 index 0000000000..621000152f --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/IndexColumnDescriptor.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.io.Serializable; +import java.util.Objects; +import org.apache.ignite.internal.tostring.S; + +/** + * Indexed column descriptor. + */ +public class IndexColumnDescriptor implements Serializable { + private static final long serialVersionUID = 5750677168056750717L; + + private final String name; + + private final ColumnCollation collation; + + public IndexColumnDescriptor(String name, ColumnCollation collation) { + this.name = name; + this.collation = Objects.requireNonNull(collation, "collation"); + } + + public String name() { + return name; + } + + public ColumnCollation collation() { + return collation; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/IndexDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/IndexDescriptor.java new file mode 100644 index 0000000000..99feaf15e3 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/IndexDescriptor.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import org.apache.ignite.internal.tostring.S; + +/** + * Index descriptor base class. + */ +public abstract class IndexDescriptor extends ObjectDescriptor { + private static final long serialVersionUID = -8045949593661301287L; + + /** Table id. */ + private final int tableId; + + /** Unique constraint flag. */ + private boolean unique; + + /** Write only flag. {@code True} when index is building. */ + private boolean writeOnly; + + IndexDescriptor(int id, String name, int tableId, boolean unique) { + super(id, Type.INDEX, name); + this.tableId = tableId; + this.unique = unique; + } + + public int tableId() { + return tableId; + } + + public boolean unique() { + return unique; + } + + public boolean writeOnly() { + return writeOnly; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/ObjectDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/ObjectDescriptor.java new file mode 100644 index 0000000000..eabd9e5dff --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/ObjectDescriptor.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.io.Serializable; +import java.util.Objects; +import org.apache.ignite.internal.tostring.S; + +/** + * Base class for catalog objects. + * TODO: IGNITE-18535 Implement custom effective serialization instead. + */ +public abstract class ObjectDescriptor implements Serializable { + private static final long serialVersionUID = -6525237234280004860L; + private final int id; + private final String name; + private final Type type; + + ObjectDescriptor(int id, Type type, String name) { + this.id = id; + this.type = Objects.requireNonNull(type, "type"); + this.name = Objects.requireNonNull(name, "name"); + } + + /** Returns id of the described object. */ + public int id() { + return id; + } + + /** Returns name of the described object. */ + public String name() { + return name; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } + + /** Catalog object type. */ + enum Type { + SCHEMA, + TABLE, + INDEX + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/SchemaDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/SchemaDescriptor.java new file mode 100644 index 0000000000..4a4c53736f --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/SchemaDescriptor.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.apache.ignite.internal.tostring.IgniteToStringExclude; +import org.apache.ignite.internal.tostring.S; + +/** + * Schema definition contains database schema objects. + */ +public class SchemaDescriptor extends ObjectDescriptor { + private static final long serialVersionUID = -233494425779955410L; + + private final int version; + private final TableDescriptor[] tables; + private final IndexDescriptor[] indexes; + + @IgniteToStringExclude + private transient Map<String, TableDescriptor> tablesMap; + @IgniteToStringExclude + private transient Map<String, IndexDescriptor> indexesMap; //TODO: IGNITE-18535 Drop if not used. + + public SchemaDescriptor(int id, String name, int version, TableDescriptor[] tables, IndexDescriptor[] indexes) { + super(id, Type.SCHEMA, name); + this.version = version; + this.tables = Objects.requireNonNull(tables, "tables"); + this.indexes = Objects.requireNonNull(indexes, "indexes"); + + rebuildMaps(); + } + + public int version() { + return version; + } + + TableDescriptor[] tables() { + return tables; + } + + IndexDescriptor[] indexes() { + return indexes; + } + + public TableDescriptor table(String name) { + return tablesMap.get(name); + } + + public IndexDescriptor index(String name) { + return indexesMap.get(name); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + rebuildMaps(); + } + + private void rebuildMaps() { + tablesMap = Arrays.stream(tables).collect(Collectors.toMap(ObjectDescriptor::name, Function.identity())); + indexesMap = Arrays.stream(indexes).collect(Collectors.toMap(ObjectDescriptor::name, Function.identity())); + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/SortedIndexDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/SortedIndexDescriptor.java new file mode 100644 index 0000000000..cfc59ee4c4 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/SortedIndexDescriptor.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + + +import java.util.List; +import java.util.Objects; +import org.apache.ignite.internal.tostring.S; + +/** + * Sorted index descriptor. + */ +public class SortedIndexDescriptor extends IndexDescriptor { + private static final long serialVersionUID = 2085714310150728611L; + + private final List<IndexColumnDescriptor> columns; + + /** + * Constructs a sorted description. + * + * @param id Id of the index. + * @param name Name of the index. + * @param tableId Id of the table index belongs to. + * @param columns A list of columns descriptors. + * @throws IllegalArgumentException If columns list contains duplicates or columns size doesn't match the collations size. + */ + public SortedIndexDescriptor(int id, String name, int tableId, List<IndexColumnDescriptor> columns) { + super(id, name, tableId, false); + + this.columns = Objects.requireNonNull(columns, "columns"); + } + + public List<IndexColumnDescriptor> columns() { + return columns; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} + + diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/TableColumnDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/TableColumnDescriptor.java new file mode 100644 index 0000000000..4a7d9aeb60 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/TableColumnDescriptor.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.io.Serializable; +import java.util.Objects; +import org.apache.ignite.internal.tostring.S; +import org.apache.ignite.sql.ColumnType; + +/** + * Table column descriptor. + */ +public class TableColumnDescriptor implements Serializable { + private static final long serialVersionUID = 7684890562398520509L; + + private final String name; + private final ColumnType type; + private final boolean nullable; + /** Max length constraint. */ + private int length; + private int precision; + private int scale; + private String defaultValueExpression; + + public TableColumnDescriptor(String name, ColumnType type, boolean nullable) { + this.name = Objects.requireNonNull(name, "name"); + this.type = Objects.requireNonNull(type); + this.nullable = nullable; + } + + public String name() { + return name; + } + + public boolean nullable() { + return nullable; + } + + public ColumnType type() { + return type; + } + + public int precision() { + return precision; + } + + public int scale() { + return scale; + } + + public int length() { + return length; + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/TableDescriptor.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/TableDescriptor.java new file mode 100644 index 0000000000..6babceaf33 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/descriptors/TableDescriptor.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.descriptors; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.apache.ignite.internal.tostring.IgniteToStringExclude; +import org.apache.ignite.internal.tostring.S; +import org.jetbrains.annotations.Nullable; + +/** + * Table descriptor. + */ +public class TableDescriptor extends ObjectDescriptor { + private static final long serialVersionUID = -2021394971104316570L; + + private final int zoneId = 0; + private final int engineId = 0; + + private final TableColumnDescriptor[] columns; + private final String[] primaryKeyColumns; + private final String[] colocationColumns; + + @IgniteToStringExclude + private transient Map<String, TableColumnDescriptor> columnsMap; + + public TableDescriptor(int id, String name, TableColumnDescriptor[] columns, String[] pkCols, @Nullable String[] colocationCols) { + super(id, Type.TABLE, name); + + this.columns = Objects.requireNonNull(columns); + primaryKeyColumns = Objects.requireNonNull(pkCols, "No primary key columns."); + colocationColumns = Objects.requireNonNullElse(colocationCols, primaryKeyColumns); + + this.columnsMap = Arrays.stream(columns).collect(Collectors.toMap(TableColumnDescriptor::name, Function.identity())); + + // TODO: IGNITE-18535 Throw proper exceptions. + assert !columnsMap.isEmpty() : "No columns."; + assert primaryKeyColumns.length > 0 : "No primary key columns."; + assert colocationColumns.length > 0 : "No colocation columns."; + + assert Arrays.stream(primaryKeyColumns).noneMatch(c -> Objects.requireNonNull(columnsMap.get(c), c).nullable()); + //noinspection ArrayEquality + assert primaryKeyColumns == colocationColumns || Set.of(primaryKeyColumns).containsAll(List.of(colocationColumns)); + } + + public int zoneId() { + return zoneId; + } + + public int engineId() { + return engineId; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.columnsMap = Arrays.stream(columns).collect(Collectors.toMap(TableColumnDescriptor::name, Function.identity())); + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return S.toString(this); + } +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/CatalogEvent.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/CatalogEvent.java new file mode 100644 index 0000000000..366c4858d1 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/CatalogEvent.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.events; + +import org.apache.ignite.internal.manager.Event; + +/** + * TODO: IGNITE-18535 Javadoc. + */ +public enum CatalogEvent implements Event { +} diff --git a/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/CatalogEventParameters.java b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/CatalogEventParameters.java new file mode 100644 index 0000000000..6b974c4a72 --- /dev/null +++ b/modules/catalog/src/main/java/org/apache/ignite/internal/catalog/events/CatalogEventParameters.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.catalog.events; + +import org.apache.ignite.internal.manager.EventParameters; + +/** + * TODO: IGNITE-18535 Javadoc. + */ +public class CatalogEventParameters extends EventParameters { + /** + * Constructor. + * + * @param causalityToken Causality token. + */ + public CatalogEventParameters(long causalityToken) { + super(causalityToken); + } +} diff --git a/settings.gradle b/settings.gradle index ca9b7f3ba7..f33fd8d336 100644 --- a/settings.gradle +++ b/settings.gradle @@ -67,6 +67,7 @@ include(':ignite-distribution-zones') include(':ignite-placement-driver') include(':ignite-code-deployment') include(':ignite-security') +include(':ignite-catalog') project(":ignite-examples").projectDir = file('examples') project(":ignite-page-memory").projectDir = file('modules/page-memory') @@ -119,6 +120,7 @@ project(":ignite-distribution-zones").projectDir = file('modules/distribution-zo project(":ignite-placement-driver").projectDir = file('modules/placement-driver') project(":ignite-code-deployment").projectDir = file('modules/code-deployment') project(":ignite-security").projectDir = file('modules/security') +project(":ignite-catalog").projectDir = file('modules/catalog') ext.isCiServer = System.getenv().containsKey("IGNITE_CI")
