http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/gen/thrift/gen-rb/thrift_hive_metastore.rb ---------------------------------------------------------------------- diff --git a/metastore/src/gen/thrift/gen-rb/thrift_hive_metastore.rb b/metastore/src/gen/thrift/gen-rb/thrift_hive_metastore.rb index e782bb5..99a764e 100644 --- a/metastore/src/gen/thrift/gen-rb/thrift_hive_metastore.rb +++ b/metastore/src/gen/thrift/gen-rb/thrift_hive_metastore.rb @@ -318,6 +318,24 @@ module ThriftHiveMetastore return end + def create_table_with_constraints(tbl, primaryKeys, foreignKeys) + send_create_table_with_constraints(tbl, primaryKeys, foreignKeys) + recv_create_table_with_constraints() + end + + def send_create_table_with_constraints(tbl, primaryKeys, foreignKeys) + send_message('create_table_with_constraints', Create_table_with_constraints_args, :tbl => tbl, :primaryKeys => primaryKeys, :foreignKeys => foreignKeys) + end + + def recv_create_table_with_constraints() + result = receive_message(Create_table_with_constraints_result) + raise result.o1 unless result.o1.nil? + raise result.o2 unless result.o2.nil? + raise result.o3 unless result.o3.nil? + raise result.o4 unless result.o4.nil? + return + end + def drop_table(dbname, name, deleteData) send_drop_table(dbname, name, deleteData) recv_drop_table() @@ -1324,6 +1342,40 @@ module ThriftHiveMetastore raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_index_names failed: unknown result') end + def get_primary_keys(request) + send_get_primary_keys(request) + return recv_get_primary_keys() + end + + def send_get_primary_keys(request) + send_message('get_primary_keys', Get_primary_keys_args, :request => request) + end + + def recv_get_primary_keys() + result = receive_message(Get_primary_keys_result) + return result.success unless result.success.nil? + raise result.o1 unless result.o1.nil? + raise result.o2 unless result.o2.nil? + raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_primary_keys failed: unknown result') + end + + def get_foreign_keys(request) + send_get_foreign_keys(request) + return recv_get_foreign_keys() + end + + def send_get_foreign_keys(request) + send_message('get_foreign_keys', Get_foreign_keys_args, :request => request) + end + + def recv_get_foreign_keys() + result = receive_message(Get_foreign_keys_result) + return result.success unless result.success.nil? + raise result.o1 unless result.o1.nil? + raise result.o2 unless result.o2.nil? + raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'get_foreign_keys failed: unknown result') + end + def update_table_column_statistics(stats_obj) send_update_table_column_statistics(stats_obj) return recv_update_table_column_statistics() @@ -2635,6 +2687,23 @@ module ThriftHiveMetastore write_result(result, oprot, 'create_table_with_environment_context', seqid) end + def process_create_table_with_constraints(seqid, iprot, oprot) + args = read_args(iprot, Create_table_with_constraints_args) + result = Create_table_with_constraints_result.new() + begin + @handler.create_table_with_constraints(args.tbl, args.primaryKeys, args.foreignKeys) + rescue ::AlreadyExistsException => o1 + result.o1 = o1 + rescue ::InvalidObjectException => o2 + result.o2 = o2 + rescue ::MetaException => o3 + result.o3 = o3 + rescue ::NoSuchObjectException => o4 + result.o4 = o4 + end + write_result(result, oprot, 'create_table_with_constraints', seqid) + end + def process_drop_table(seqid, iprot, oprot) args = read_args(iprot, Drop_table_args) result = Drop_table_result.new() @@ -3432,6 +3501,32 @@ module ThriftHiveMetastore write_result(result, oprot, 'get_index_names', seqid) end + def process_get_primary_keys(seqid, iprot, oprot) + args = read_args(iprot, Get_primary_keys_args) + result = Get_primary_keys_result.new() + begin + result.success = @handler.get_primary_keys(args.request) + rescue ::MetaException => o1 + result.o1 = o1 + rescue ::NoSuchObjectException => o2 + result.o2 = o2 + end + write_result(result, oprot, 'get_primary_keys', seqid) + end + + def process_get_foreign_keys(seqid, iprot, oprot) + args = read_args(iprot, Get_foreign_keys_args) + result = Get_foreign_keys_result.new() + begin + result.success = @handler.get_foreign_keys(args.request) + rescue ::MetaException => o1 + result.o1 = o1 + rescue ::NoSuchObjectException => o2 + result.o2 = o2 + end + write_result(result, oprot, 'get_foreign_keys', seqid) + end + def process_update_table_column_statistics(seqid, iprot, oprot) args = read_args(iprot, Update_table_column_statistics_args) result = Update_table_column_statistics_result.new() @@ -4817,6 +4912,48 @@ module ThriftHiveMetastore ::Thrift::Struct.generate_accessors self end + class Create_table_with_constraints_args + include ::Thrift::Struct, ::Thrift::Struct_Union + TBL = 1 + PRIMARYKEYS = 2 + FOREIGNKEYS = 3 + + FIELDS = { + TBL => {:type => ::Thrift::Types::STRUCT, :name => 'tbl', :class => ::Table}, + PRIMARYKEYS => {:type => ::Thrift::Types::LIST, :name => 'primaryKeys', :element => {:type => ::Thrift::Types::STRUCT, :class => ::SQLPrimaryKey}}, + FOREIGNKEYS => {:type => ::Thrift::Types::LIST, :name => 'foreignKeys', :element => {:type => ::Thrift::Types::STRUCT, :class => ::SQLForeignKey}} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + end + + class Create_table_with_constraints_result + include ::Thrift::Struct, ::Thrift::Struct_Union + O1 = 1 + O2 = 2 + O3 = 3 + O4 = 4 + + FIELDS = { + O1 => {:type => ::Thrift::Types::STRUCT, :name => 'o1', :class => ::AlreadyExistsException}, + O2 => {:type => ::Thrift::Types::STRUCT, :name => 'o2', :class => ::InvalidObjectException}, + O3 => {:type => ::Thrift::Types::STRUCT, :name => 'o3', :class => ::MetaException}, + O4 => {:type => ::Thrift::Types::STRUCT, :name => 'o4', :class => ::NoSuchObjectException} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + end + class Drop_table_args include ::Thrift::Struct, ::Thrift::Struct_Union DBNAME = 1 @@ -7205,6 +7342,78 @@ module ThriftHiveMetastore ::Thrift::Struct.generate_accessors self end + class Get_primary_keys_args + include ::Thrift::Struct, ::Thrift::Struct_Union + REQUEST = 1 + + FIELDS = { + REQUEST => {:type => ::Thrift::Types::STRUCT, :name => 'request', :class => ::PrimaryKeysRequest} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + end + + class Get_primary_keys_result + include ::Thrift::Struct, ::Thrift::Struct_Union + SUCCESS = 0 + O1 = 1 + O2 = 2 + + FIELDS = { + SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::PrimaryKeysResponse}, + O1 => {:type => ::Thrift::Types::STRUCT, :name => 'o1', :class => ::MetaException}, + O2 => {:type => ::Thrift::Types::STRUCT, :name => 'o2', :class => ::NoSuchObjectException} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + end + + class Get_foreign_keys_args + include ::Thrift::Struct, ::Thrift::Struct_Union + REQUEST = 1 + + FIELDS = { + REQUEST => {:type => ::Thrift::Types::STRUCT, :name => 'request', :class => ::ForeignKeysRequest} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + end + + class Get_foreign_keys_result + include ::Thrift::Struct, ::Thrift::Struct_Union + SUCCESS = 0 + O1 = 1 + O2 = 2 + + FIELDS = { + SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::ForeignKeysResponse}, + O1 => {:type => ::Thrift::Types::STRUCT, :name => 'o1', :class => ::MetaException}, + O2 => {:type => ::Thrift::Types::STRUCT, :name => 'o2', :class => ::NoSuchObjectException} + } + + def struct_fields; FIELDS; end + + def validate + end + + ::Thrift::Struct.generate_accessors self + end + class Update_table_column_statistics_args include ::Thrift::Struct, ::Thrift::Struct_Union STATS_OBJ = 1
http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java index c9fadad..ed2057a 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimaps; + import org.apache.commons.cli.OptionBuilder; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; @@ -112,6 +113,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jdo.JDOException; + import java.io.IOException; import java.nio.ByteBuffer; import java.text.DateFormat; @@ -1310,7 +1312,7 @@ public class HiveMetaStore extends ThriftHiveMetastore { } private void create_table_core(final RawStore ms, final Table tbl, - final EnvironmentContext envContext) + final EnvironmentContext envContext, List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) throws AlreadyExistsException, MetaException, InvalidObjectException, NoSuchObjectException { @@ -1395,7 +1397,11 @@ public class HiveMetaStore extends ThriftHiveMetastore { tbl.getParameters().get(hive_metastoreConstants.DDL_TIME) == null) { tbl.putToParameters(hive_metastoreConstants.DDL_TIME, Long.toString(time)); } - ms.createTable(tbl); + if (primaryKeys == null && foreignKeys == null) { + ms.createTable(tbl); + } else { + ms.createTableWithConstraints(tbl, primaryKeys, foreignKeys); + } success = ms.commitTransaction(); } finally { @@ -1428,7 +1434,7 @@ public class HiveMetaStore extends ThriftHiveMetastore { boolean success = false; Exception ex = null; try { - create_table_core(getMS(), tbl, envContext); + create_table_core(getMS(), tbl, envContext, null, null); success = true; } catch (NoSuchObjectException e) { ex = e; @@ -1449,6 +1455,34 @@ public class HiveMetaStore extends ThriftHiveMetastore { } } + @Override + public void create_table_with_constraints(final Table tbl, + final List<SQLPrimaryKey> primaryKeys, final List<SQLForeignKey> foreignKeys) + throws AlreadyExistsException, MetaException, InvalidObjectException { + startFunction("create_table", ": " + tbl.toString()); + boolean success = false; + Exception ex = null; + try { + create_table_core(getMS(), tbl, null, primaryKeys, foreignKeys); + success = true; + } catch (NoSuchObjectException e) { + ex = e; + throw new InvalidObjectException(e.getMessage()); + } catch (Exception e) { + ex = e; + if (e instanceof MetaException) { + throw (MetaException) e; + } else if (e instanceof InvalidObjectException) { + throw (InvalidObjectException) e; + } else if (e instanceof AlreadyExistsException) { + throw (AlreadyExistsException) e; + } else { + throw newMetaException(e); + } + } finally { + endFunction("create_table", success, ex, tbl.getTableName()); + } + } private boolean is_table_exists(RawStore ms, String dbname, String name) throws MetaException { return (ms.getTable(dbname, name) != null); @@ -6131,6 +6165,63 @@ public class HiveMetaStore extends ThriftHiveMetastore { throws TException { return new GetChangeVersionResult(getMS().getChangeVersion(req.getTopic())); } + + + @Override + public PrimaryKeysResponse get_primary_keys(PrimaryKeysRequest request) + throws MetaException, NoSuchObjectException, TException { + String db_name = request.getDb_name(); + String tbl_name = request.getTbl_name(); + startTableFunction("get_primary_keys", db_name, tbl_name); + List<SQLPrimaryKey> ret = null; + Exception ex = null; + try { + ret = getMS().getPrimaryKeys(db_name, tbl_name); + } catch (Exception e) { + ex = e; + if (e instanceof MetaException) { + throw (MetaException) e; + } else if (e instanceof NoSuchObjectException) { + throw (NoSuchObjectException) e; + } else { + throw newMetaException(e); + } + } finally { + endFunction("get_primary_keys", ret != null, ex, tbl_name); + } + return new PrimaryKeysResponse(ret); + } + + @Override + public ForeignKeysResponse get_foreign_keys(ForeignKeysRequest request) throws MetaException, + NoSuchObjectException, TException { + String parent_db_name = request.getParent_db_name(); + String parent_tbl_name = request.getParent_tbl_name(); + String foreign_db_name = request.getForeign_db_name(); + String foreign_tbl_name = request.getForeign_tbl_name(); + startFunction("get_foreign_keys", " : parentdb=" + parent_db_name + + " parenttbl=" + parent_tbl_name + " foreigndb=" + foreign_db_name + + " foreigntbl=" + foreign_tbl_name); + List<SQLForeignKey> ret = null; + Exception ex = null; + try { + ret = getMS().getForeignKeys(parent_db_name, parent_tbl_name, + foreign_db_name, foreign_tbl_name); + } catch (Exception e) { + ex = e; + if (e instanceof MetaException) { + throw (MetaException) e; + } else if (e instanceof NoSuchObjectException) { + throw (NoSuchObjectException) e; + } else { + throw newMetaException(e); + } + } finally { + endFunction("get_foreign_keys", ret != null, ex, foreign_tbl_name); + } + return new ForeignKeysResponse(ret); + } + } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java index cdd12ab..7d37d07 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java @@ -50,6 +50,7 @@ import org.apache.hadoop.hive.metastore.api.EnvironmentContext; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.FireEventRequest; import org.apache.hadoop.hive.metastore.api.FireEventResponse; +import org.apache.hadoop.hive.metastore.api.ForeignKeysRequest; import org.apache.hadoop.hive.metastore.api.Function; import org.apache.hadoop.hive.metastore.api.GetAllFunctionsResponse; import org.apache.hadoop.hive.metastore.api.GetChangeVersionRequest; @@ -94,12 +95,15 @@ import org.apache.hadoop.hive.metastore.api.PartitionEventType; import org.apache.hadoop.hive.metastore.api.PartitionsByExprRequest; import org.apache.hadoop.hive.metastore.api.PartitionsByExprResult; import org.apache.hadoop.hive.metastore.api.PartitionsStatsRequest; +import org.apache.hadoop.hive.metastore.api.PrimaryKeysRequest; import org.apache.hadoop.hive.metastore.api.PrincipalPrivilegeSet; import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.PutFileMetadataRequest; import org.apache.hadoop.hive.metastore.api.RequestPartsSpec; import org.apache.hadoop.hive.metastore.api.Role; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.SetPartitionsStatsRequest; import org.apache.hadoop.hive.metastore.api.ShowCompactRequest; import org.apache.hadoop.hive.metastore.api.ShowCompactResponse; @@ -136,6 +140,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.security.auth.login.LoginException; + import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; @@ -736,7 +741,32 @@ public class HiveMetaStoreClient implements IMetaStoreClient { } } - /** + @Override + public void createTableWithConstraints(Table tbl, + List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) + throws AlreadyExistsException, InvalidObjectException, + MetaException, NoSuchObjectException, TException { + HiveMetaHook hook = getHook(tbl); + if (hook != null) { + hook.preCreateTable(tbl); + } + boolean success = false; + try { + // Subclasses can override this step (for example, for temporary tables) + client.create_table_with_constraints(tbl, primaryKeys, foreignKeys); + if (hook != null) { + hook.commitCreateTable(tbl); + } + success = true; + } finally { + if (!success && (hook != null)) { + hook.rollbackCreateTable(tbl); + } + } + } + + +/** * @param type * @return true or false * @throws AlreadyExistsException @@ -1528,6 +1558,19 @@ public class HiveMetaStoreClient implements IMetaStoreClient { return filterHook.filterIndexes(client.get_indexes(dbName, tblName, max)); } + @Override + public List<SQLPrimaryKey> getPrimaryKeys(PrimaryKeysRequest req) + throws MetaException, NoSuchObjectException, TException { + return client.get_primary_keys(req).getPrimaryKeys(); + } + + @Override + public List<SQLForeignKey> getForeignKeys(ForeignKeysRequest req) throws MetaException, + NoSuchObjectException, TException { + return client.get_foreign_keys(req).getForeignKeys(); + } + + /** {@inheritDoc} */ @Override public boolean updateTableColumnStatistics(ColumnStatistics statsObj) @@ -2375,4 +2418,5 @@ public class HiveMetaStoreClient implements IMetaStoreClient { public long getChangeVersion(String topic) throws TException { return client.get_change_version(new GetChangeVersionRequest(topic)).getVersion(); } + } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java b/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java index 39cf927..c900a2d 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java @@ -37,6 +37,7 @@ import org.apache.hadoop.hive.metastore.api.EnvironmentContext; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.FireEventRequest; import org.apache.hadoop.hive.metastore.api.FireEventResponse; +import org.apache.hadoop.hive.metastore.api.ForeignKeysRequest; import org.apache.hadoop.hive.metastore.api.Function; import org.apache.hadoop.hive.metastore.api.GetAllFunctionsResponse; import org.apache.hadoop.hive.metastore.api.GetOpenTxnsInfoResponse; @@ -64,10 +65,13 @@ import org.apache.hadoop.hive.metastore.api.NotificationEventResponse; import org.apache.hadoop.hive.metastore.api.OpenTxnsResponse; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.PartitionEventType; +import org.apache.hadoop.hive.metastore.api.PrimaryKeysRequest; import org.apache.hadoop.hive.metastore.api.PrincipalPrivilegeSet; import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.Role; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.SetPartitionsStatsRequest; import org.apache.hadoop.hive.metastore.api.ShowCompactResponse; import org.apache.hadoop.hive.metastore.api.ShowLocksResponse; @@ -1554,4 +1558,16 @@ public interface IMetaStoreClient { boolean allParts) throws TException; long getChangeVersion(String topic) throws TException; + + List<SQLPrimaryKey> getPrimaryKeys(PrimaryKeysRequest request) + throws MetaException, NoSuchObjectException, TException; + + List<SQLForeignKey> getForeignKeys(ForeignKeysRequest request) throws MetaException, + NoSuchObjectException, TException; + + void createTableWithConstraints( + org.apache.hadoop.hive.metastore.api.Table tTbl, + List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) + throws AlreadyExistsException, InvalidObjectException, MetaException, NoSuchObjectException, TException; + } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java b/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java index 06e9f78..744512f 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java @@ -53,10 +53,13 @@ import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.Order; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.PrincipalType; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.SerDeInfo; import org.apache.hadoop.hive.metastore.api.SkewedInfo; import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import org.apache.hadoop.hive.metastore.api.Table; +import org.apache.hadoop.hive.metastore.model.MConstraint; import org.apache.hadoop.hive.metastore.model.MDatabase; import org.apache.hadoop.hive.metastore.model.MPartitionColumnStatistics; import org.apache.hadoop.hive.metastore.model.MTableColumnStatistics; @@ -1809,4 +1812,135 @@ class MetaStoreDirectSql { } return result; } + + public List<SQLForeignKey> getForeignKeys(String parent_db_name, String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) throws MetaException { + List<SQLForeignKey> ret = new ArrayList<SQLForeignKey>(); + String queryText = + "SELECT \"D2\".\"NAME\", \"T2\".\"TBL_NAME\", \"C2\".\"COLUMN_NAME\"," + + "\"DBS\".\"NAME\", \"TBLS\".\"TBL_NAME\", \"COLUMNS_V2\".\"COLUMN_NAME\", " + + "\"KEY_CONSTRAINTS\".\"POSITION\", \"KEY_CONSTRAINTS\".\"UPDATE_RULE\", \"KEY_CONSTRAINTS\".\"DELETE_RULE\", " + + "\"KEY_CONSTRAINTS\".\"CONSTRAINT_NAME\" , \"KEY_CONSTRAINTS2\".\"CONSTRAINT_NAME\", \"KEY_CONSTRAINTS\".\"ENABLE_VALIDATE_RELY\"" + + " FROM \"TBLS\" " + + " INNER JOIN \"KEY_CONSTRAINTS\" ON \"TBLS\".\"TBL_ID\" = \"KEY_CONSTRAINTS\".\"CHILD_TBL_ID\" " + + " INNER JOIN \"KEY_CONSTRAINTS\" \"KEY_CONSTRAINTS2\" ON \"KEY_CONSTRAINTS2\".\"PARENT_TBL_ID\" = \"KEY_CONSTRAINTS\".\"PARENT_TBL_ID\" " + + " INNER JOIN \"DBS\" ON \"TBLS\".\"DB_ID\" = \"DBS\".\"DB_ID\" " + + " INNER JOIN \"TBLS\" \"T2\" ON \"KEY_CONSTRAINTS\".\"PARENT_TBL_ID\" = \"T2\".\"TBL_ID\" " + + " INNER JOIN \"DBS\" \"D2\" ON \"T2\".\"DB_ID\" = \"D2\".\"DB_ID\" " + + " INNER JOIN \"COLUMNS_V2\" ON \"COLUMNS_V2\".\"CD_ID\" = \"KEY_CONSTRAINTS\".\"CHILD_CD_ID\" " + + " INNER JOIN \"COLUMNS_V2\" \"C2\" ON \"C2\".\"CD_ID\" = \"KEY_CONSTRAINTS\".\"PARENT_CD_ID\" " + + " WHERE \"KEY_CONSTRAINTS\".\"CONSTRAINT_TYPE\" = " + + MConstraint.FOREIGN_KEY_CONSTRAINT + + " AND \"KEY_CONSTRAINTS2\".\"CONSTRAINT_TYPE\" = " + + MConstraint.PRIMARY_KEY_CONSTRAINT + + (foreign_db_name == null ? "" : "\"DBS\".\"NAME\" = ? AND") + + (foreign_tbl_name == null ? "" : " \"TBLS\".\"TBL_NAME\" = ? AND ") + + (parent_tbl_name == null ? "" : " \"T2\".\"TBL_NAME\" = ? AND ") + + (parent_db_name == null ? "" : "\"D2\".\"NAME\" = ?") ; + + queryText = queryText.trim(); + if (queryText.endsWith("WHERE")) { + queryText = queryText.substring(0, queryText.length()-5); + } + if (queryText.endsWith("AND")) { + queryText = queryText.substring(0, queryText.length()-3); + } + List<String> pms = new ArrayList<String>(); + if (foreign_db_name != null) { + pms.add(foreign_db_name); + } + if (foreign_tbl_name != null) { + pms.add(foreign_tbl_name); + } + if (parent_tbl_name != null) { + pms.add(parent_tbl_name); + } + if (parent_db_name != null) { + pms.add(parent_db_name); + } + + Query queryParams = pm.newQuery("javax.jdo.query.SQL", queryText); + List<Object[]> sqlResult = ensureList(executeWithArray( + queryParams, pms.toArray(), queryText)); + + if (!sqlResult.isEmpty()) { + for (Object[] line : sqlResult) { + int enableValidateRely = extractSqlInt(line[11]); + boolean enable = (enableValidateRely & 4) != 0; + boolean validate = (enableValidateRely & 2) != 0; + boolean rely = (enableValidateRely & 1) != 0; + SQLForeignKey currKey = new SQLForeignKey( + extractSqlString(line[0]), + extractSqlString(line[1]), + extractSqlString(line[2]), + extractSqlString(line[3]), + extractSqlString(line[4]), + extractSqlString(line[5]), + extractSqlInt(line[6]), + extractSqlInt(line[7]), + extractSqlInt(line[8]), + extractSqlString(line[9]), + extractSqlString(line[10]), + enable, + validate, + rely + ); + ret.add(currKey); + } + } + return ret; + } + + public List<SQLPrimaryKey> getPrimaryKeys(String db_name, String tbl_name) throws MetaException { + List<SQLPrimaryKey> ret = new ArrayList<SQLPrimaryKey>(); + String queryText = + "SELECT \"DBS\".\"NAME\", \"TBLS\".\"TBL_NAME\", \"COLUMNS_V2\".\"COLUMN_NAME\"," + + "\"KEY_CONSTRAINTS\".\"POSITION\", " + + "\"KEY_CONSTRAINTS\".\"CONSTRAINT_NAME\", \"KEY_CONSTRAINTS\".\"ENABLE_VALIDATE_RELY\" " + + " FROM \"TBLS\" " + + " INNER JOIN \"KEY_CONSTRAINTS\" ON \"TBLS\".\"TBL_ID\" = \"KEY_CONSTRAINTS\".\"PARENT_TBL_ID\" " + + " INNER JOIN \"DBS\" ON \"TBLS\".\"DB_ID\" = \"DBS\".\"DB_ID\" " + + " INNER JOIN \"TBLS\" ON \"KEY_CONSTRAINTS\".\"PARENT_TBL_ID\" = \"TBLS\".\"TBL_ID\" " + + " INNER JOIN \"COLUMNS_V2\" ON \"COLUMNS_V2\".\"CD_ID\" = \"KEY_CONSTRAINTS\".\"PARENT_CD_ID\" " + + " WHERE \"KEY_CONSTRAINTS\".\"CONSTRAINT_TYPE\" = "+ MConstraint.PRIMARY_KEY_CONSTRAINT + " AND " + + (db_name == null ? "" : "\"DBS\".\"NAME\" = ? AND") + + (tbl_name == null ? "" : " \"TBLS\".\"TBL_NAME\" = ? ") ; + + queryText = queryText.trim(); + if (queryText.endsWith("WHERE")) { + queryText = queryText.substring(0, queryText.length()-5); + } + if (queryText.endsWith("AND")) { + queryText = queryText.substring(0, queryText.length()-3); + } + List<String> pms = new ArrayList<String>(); + if (db_name != null) { + pms.add(db_name); + } + if (tbl_name != null) { + pms.add(tbl_name); + } + + Query queryParams = pm.newQuery("javax.jdo.query.SQL", queryText); + List<Object[]> sqlResult = ensureList(executeWithArray( + queryParams, pms.toArray(), queryText)); + + if (!sqlResult.isEmpty()) { + for (Object[] line : sqlResult) { + int enableValidateRely = extractSqlInt(line[5]); + boolean enable = (enableValidateRely & 4) != 0; + boolean validate = (enableValidateRely & 2) != 0; + boolean rely = (enableValidateRely & 1) != 0; + SQLPrimaryKey currKey = new SQLPrimaryKey( + extractSqlString(line[0]), + extractSqlString(line[1]), + extractSqlString(line[2]), + extractSqlInt(line[3]), extractSqlString(line[4]), + enable, + validate, + rely); + ret.add(currKey); + } + } + return ret; + } } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java index ac293b9..ae6f084 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -54,6 +54,7 @@ import javax.jdo.Transaction; import javax.jdo.datastore.DataStoreCache; import javax.jdo.identity.IntIdentity; +import org.apache.commons.lang.ArrayUtils; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; @@ -97,6 +98,8 @@ import org.apache.hadoop.hive.metastore.api.ResourceType; import org.apache.hadoop.hive.metastore.api.ResourceUri; import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.SerDeInfo; import org.apache.hadoop.hive.metastore.api.SkewedInfo; import org.apache.hadoop.hive.metastore.api.StorageDescriptor; @@ -108,6 +111,7 @@ import org.apache.hadoop.hive.metastore.api.UnknownPartitionException; import org.apache.hadoop.hive.metastore.api.UnknownTableException; import org.apache.hadoop.hive.metastore.model.MChangeVersion; import org.apache.hadoop.hive.metastore.model.MColumnDescriptor; +import org.apache.hadoop.hive.metastore.model.MConstraint; import org.apache.hadoop.hive.metastore.model.MDBPrivilege; import org.apache.hadoop.hive.metastore.model.MDatabase; import org.apache.hadoop.hive.metastore.model.MDelegationToken; @@ -899,12 +903,31 @@ public class ObjectStore implements RawStore, Configurable { } @Override + public void createTableWithConstraints(Table tbl, + List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) + throws InvalidObjectException, MetaException { + boolean success = false; + try { + openTransaction(); + createTable(tbl); + addPrimaryKeys(primaryKeys); + addForeignKeys(foreignKeys); + success = commitTransaction(); + } finally { + if (!success) { + rollbackTransaction(); + } + } + } + + @Override public void createTable(Table tbl) throws InvalidObjectException, MetaException { boolean commited = false; try { openTransaction(); MTable mtbl = convertToMTable(tbl); pm.makePersistent(mtbl); + PrincipalPrivilegeSet principalPrivs = tbl.getPrivileges(); List<Object> toPersistPrivObjs = new ArrayList<Object>(); if (principalPrivs != null) { @@ -1328,7 +1351,7 @@ public class ObjectStore implements RawStore, Configurable { // A new table is always created with a new column descriptor return new MTable(HiveStringUtils.normalizeIdentifier(tbl.getTableName()), mdb, convertToMStorageDescriptor(tbl.getSd()), tbl.getOwner(), tbl - .getCreateTime(), tbl.getLastAccessTime(), tbl.getRetention(), + .getCreateTime(), tbl.getLastAccessTime(), tbl.getRetention(), convertToMFieldSchemas(tbl.getPartitionKeys()), tbl.getParameters(), tbl.getViewOriginalText(), tbl.getViewExpandedText(), tableType); @@ -3200,6 +3223,165 @@ public class ObjectStore implements RawStore, Configurable { return sds; } + private MColumnDescriptor getColumnFromTable(MTable mtbl, String col) { + for (MFieldSchema mfs: mtbl.getSd().getCD().getCols()) { + if (mfs.getName().equals(col)) { + List<MFieldSchema> mfsl = new ArrayList<MFieldSchema>(); + mfsl.add(mfs); + return new MColumnDescriptor(mfsl); + } + } + return null; + } + + private boolean constraintNameAlreadyExists(String name) { + boolean commited = false; + Query constraintExistsQuery = null; + String constraintNameIfExists = null; + try { + openTransaction(); + name = HiveStringUtils.normalizeIdentifier(name); + constraintExistsQuery = pm.newQuery(MConstraint.class, "constraintName == name"); + constraintExistsQuery.declareParameters("java.lang.String name"); + constraintExistsQuery.setUnique(true); + constraintExistsQuery.setResult("name"); + constraintNameIfExists = (String) constraintExistsQuery.execute(name); + commited = commitTransaction(); + } finally { + if (!commited) { + rollbackTransaction(); + } + if (constraintExistsQuery != null) { + constraintExistsQuery.closeAll(); + } + } + return constraintNameIfExists != null && !constraintNameIfExists.isEmpty(); + } + + private String generateConstraintName(String... parameters) throws MetaException { + int hashcode = ArrayUtils.toString(parameters).hashCode(); + int counter = 0; + final int MAX_RETRIES = 10; + while (counter < MAX_RETRIES) { + String currName = (parameters.length == 0 ? "constraint_" : parameters[parameters.length-1]) + + "_" + hashcode + "_" + System.currentTimeMillis() + "_" + (counter++); + if (!constraintNameAlreadyExists(currName)) { + return currName; + } + } + throw new MetaException("Error while trying to generate the constraint name for " + ArrayUtils.toString(parameters)); + } + + private void addForeignKeys( + List<SQLForeignKey> fks) throws InvalidObjectException, + MetaException { + List<MConstraint> mpkfks = new ArrayList<MConstraint>(); + String currentConstraintName = null; + + for (int i = 0; i < fks.size(); i++) { + MTable parentTable = + getMTable(fks.get(i).getPktable_db(), fks.get(i).getPktable_name()); + MTable childTable = + getMTable(fks.get(i).getFktable_db(), fks.get(i).getFktable_name()); + MColumnDescriptor parentColumn = + getColumnFromTable(parentTable, fks.get(i).getPkcolumn_name()); + MColumnDescriptor childColumn = + getColumnFromTable(childTable, fks.get(i).getFkcolumn_name()); + if (parentTable == null) { + throw new InvalidObjectException("Parent table not found: " + fks.get(i).getPktable_name()); + } + if (childTable == null) { + throw new InvalidObjectException("Child table not found: " + fks.get(i).getFktable_name()); + } + if (parentColumn == null) { + throw new InvalidObjectException("Parent column not found: " + fks.get(i).getPkcolumn_name()); + } + if (childColumn == null) { + throw new InvalidObjectException("Child column not found" + fks.get(i).getFkcolumn_name()); + } + if (fks.get(i).getFk_name() == null) { + // When there is no explicit foreign key name associated with the constraint and the key is composite, + // we expect the foreign keys to be send in order in the input list. + // Otherwise, the below code will break. + // If this is the first column of the FK constraint, generate the foreign key name + // NB: The below code can result in race condition where duplicate names can be generated (in theory). + // However, this scenario can be ignored for practical purposes because of + // the uniqueness of the generated constraint name. + if (fks.get(i).getKey_seq() == 1) { + currentConstraintName = generateConstraintName(fks.get(i).getFktable_db(), fks.get(i).getFktable_name(), + fks.get(i).getPktable_db(), fks.get(i).getPktable_name(), + fks.get(i).getPkcolumn_name(), fks.get(i).getFkcolumn_name(), "fk"); + } + } else { + currentConstraintName = fks.get(i).getFk_name(); + } + Integer updateRule = fks.get(i).getUpdate_rule(); + Integer deleteRule = fks.get(i).getDelete_rule(); + int enableValidateRely = (fks.get(i).isEnable_cstr() ? 4 : 0) + + (fks.get(i).isValidate_cstr() ? 2 : 0) + (fks.get(i).isRely_cstr() ? 1 : 0); + MConstraint mpkfk = new MConstraint( + currentConstraintName, + MConstraint.FOREIGN_KEY_CONSTRAINT, + fks.get(i).getKey_seq(), + deleteRule, + updateRule, + enableValidateRely, + parentTable, + childTable, + parentColumn, + childColumn + ); + mpkfks.add(mpkfk); + } + pm.makePersistentAll(mpkfks); + } + + private void addPrimaryKeys(List<SQLPrimaryKey> pks) throws InvalidObjectException, + MetaException { + List<MConstraint> mpks = new ArrayList<MConstraint>(); + String constraintName = null; + for (int i = 0; i < pks.size(); i++) { + MTable parentTable = + getMTable(pks.get(i).getTable_db(), pks.get(i).getTable_name()); + MColumnDescriptor parentColumn = + getColumnFromTable(parentTable, pks.get(i).getColumn_name()); + if (parentTable == null) { + throw new InvalidObjectException("Parent table not found: " + pks.get(i).getTable_name()); + } + if (parentColumn == null) { + throw new InvalidObjectException("Parent column not found: " + pks.get(i).getColumn_name()); + } + if (getPrimaryKeyConstraintName( + parentTable.getDatabase().getName(), parentTable.getTableName()) != null) { + throw new MetaException(" Primary key already exists for: " + + parentTable.getDatabase().getName() + "." + pks.get(i).getTable_name()); + } + if (pks.get(i).getPk_name() == null) { + if (pks.get(i).getKey_seq() == 1) { + constraintName = generateConstraintName(pks.get(i).getTable_db(), pks.get(i).getTable_name(), + pks.get(i).getColumn_name(), "pk"); + } + } else { + constraintName = pks.get(i).getPk_name(); + } + int enableValidateRely = (pks.get(i).isEnable_cstr() ? 4 : 0) + + (pks.get(i).isValidate_cstr() ? 2 : 0) + (pks.get(i).isRely_cstr() ? 1 : 0); + MConstraint mpk = new MConstraint( + constraintName, + MConstraint.PRIMARY_KEY_CONSTRAINT, + pks.get(i).getKey_seq(), + null, + null, + enableValidateRely, + parentTable, + null, + parentColumn, + null); + mpks.add(mpk); + } + pm.makePersistentAll(mpks); + } + @Override public boolean addIndex(Index index) throws InvalidObjectException, MetaException { @@ -7940,4 +8122,217 @@ public class ObjectStore implements RawStore, Configurable { } } } + + @Override + public List<SQLPrimaryKey> getPrimaryKeys(String db_name, String tbl_name) throws MetaException { + try { + return getPrimaryKeysInternal(db_name, tbl_name, true, true); + } catch (NoSuchObjectException e) { + throw new MetaException(e.getMessage()); + } + } + + protected List<SQLPrimaryKey> getPrimaryKeysInternal(final String db_name, + final String tbl_name, + boolean allowSql, boolean allowJdo) + throws MetaException, NoSuchObjectException { + return new GetListHelper<SQLPrimaryKey>(db_name, tbl_name, allowSql, allowJdo) { + + @Override + protected List<SQLPrimaryKey> getSqlResult(GetHelper<List<SQLPrimaryKey>> ctx) throws MetaException { + return directSql.getPrimaryKeys(db_name, tbl_name); + } + + @Override + protected List<SQLPrimaryKey> getJdoResult( + GetHelper<List<SQLPrimaryKey>> ctx) throws MetaException, NoSuchObjectException { + return getPrimaryKeysViaJdo(db_name, tbl_name); + } + }.run(false); + } + + private List<SQLPrimaryKey> getPrimaryKeysViaJdo(String db_name, String tbl_name) throws MetaException { + boolean commited = false; + List<SQLPrimaryKey> primaryKeys = null; + Query query = null; + try { + openTransaction(); + query = pm.newQuery(MConstraint.class, + "parentTable.tableName == tbl_name && parentTable.database.name == db_name &&" + + " constraintType == MConstraint.PRIMARY_KEY_CONSTRAINT"); + query.declareParameters("java.lang.String tbl_name, java.lang.String db_name"); + Collection<?> constraints = (Collection<?>) query.execute(tbl_name, db_name); + pm.retrieveAll(constraints); + primaryKeys = new ArrayList<SQLPrimaryKey>(); + for (Iterator<?> i = constraints.iterator(); i.hasNext();) { + MConstraint currPK = (MConstraint) i.next(); + int enableValidateRely = currPK.getEnableValidateRely(); + boolean enable = (enableValidateRely & 4) != 0; + boolean validate = (enableValidateRely & 2) != 0; + boolean rely = (enableValidateRely & 1) != 0; + primaryKeys.add(new SQLPrimaryKey(db_name, + tbl_name, + currPK.getParentColumn().getCols().get(0).getName(), + currPK.getPosition(), + currPK.getConstraintName(), enable, validate, rely)); + } + commited = commitTransaction(); + } finally { + if (!commited) { + rollbackTransaction(); + } + if (query != null) { + query.closeAll(); + } + } + return primaryKeys; + } + + private String getPrimaryKeyConstraintName(String db_name, String tbl_name) throws MetaException { + boolean commited = false; + String ret = null; + Query query = null; + + try { + openTransaction(); + query = pm.newQuery(MConstraint.class, + "parentTable.tableName == tbl_name && parentTable.database.name == db_name &&" + + " constraintType == MConstraint.PRIMARY_KEY_CONSTRAINT"); + query.declareParameters("java.lang.String tbl_name, java.lang.String db_name"); + Collection<?> constraints = (Collection<?>) query.execute(tbl_name, db_name); + pm.retrieveAll(constraints); + for (Iterator<?> i = constraints.iterator(); i.hasNext();) { + MConstraint currPK = (MConstraint) i.next(); + ret = currPK.getConstraintName(); + break; + } + commited = commitTransaction(); + } finally { + if (!commited) { + rollbackTransaction(); + } + if (query != null) { + query.closeAll(); + } + } + return ret; + } + + @Override + public List<SQLForeignKey> getForeignKeys(String parent_db_name, + String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) throws MetaException { + try { + return getForeignKeysInternal(parent_db_name, + parent_tbl_name, foreign_db_name, foreign_tbl_name, true, true); + } catch (NoSuchObjectException e) { + throw new MetaException(e.getMessage()); + } + } + + protected List<SQLForeignKey> getForeignKeysInternal(final String parent_db_name, + final String parent_tbl_name, final String foreign_db_name, final String foreign_tbl_name, + boolean allowSql, boolean allowJdo) throws MetaException, NoSuchObjectException { + return new GetListHelper<SQLForeignKey>(foreign_db_name, foreign_tbl_name, allowSql, allowJdo) { + + @Override + protected List<SQLForeignKey> getSqlResult(GetHelper<List<SQLForeignKey>> ctx) throws MetaException { + return directSql.getForeignKeys(parent_db_name, + parent_tbl_name, foreign_db_name, foreign_tbl_name); + } + + @Override + protected List<SQLForeignKey> getJdoResult( + GetHelper<List<SQLForeignKey>> ctx) throws MetaException, NoSuchObjectException { + return getForeignKeysViaJdo(parent_db_name, + parent_tbl_name, foreign_db_name, foreign_tbl_name); + } + }.run(false); + } + + private List<SQLForeignKey> getForeignKeysViaJdo(String parent_db_name, + String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) throws MetaException { + boolean commited = false; + List<SQLForeignKey> foreignKeys = null; + Collection<?> constraints = null; + Query query = null; + Map<String, String> tblToConstraint = new HashMap<String, String>(); + try { + openTransaction(); + String queryText = (parent_tbl_name != null ? "parentTable.tableName == parent_tbl_name &&" : "") + + (parent_db_name != null ? "parentTable.database.name == parent_db_name &&" : "") + + (foreign_tbl_name != null ? "childTable.tableName == foreign_tbl_name &&" : "") + + (parent_db_name != null ? "childTable.database.name == foreign_db_name &&" : "") + + "constraintType == MConstraint.FOREIGN_KEY_CONSTRAINT"; + queryText = queryText.trim(); + query = pm.newQuery(MConstraint.class, queryText); + String paramText = (parent_tbl_name == null ? "" : "java.lang.String parent_tbl_name,") + + (parent_db_name == null ? "" : " java.lang.String parent_db_name, ") + + (foreign_tbl_name == null ? "" : "java.lang.String foreign_tbl_name,") + + (foreign_db_name == null ? "" : " java.lang.String foreign_db_name"); + paramText=paramText.trim(); + if (paramText.endsWith(",")) { + paramText = paramText.substring(0, paramText.length()-1); + } + query.declareParameters(paramText); + List<String> params = new ArrayList<String>(); + if (parent_tbl_name != null) { + params.add(parent_tbl_name); + } + if (parent_db_name != null) { + params.add(parent_db_name); + } + if (foreign_tbl_name != null) { + params.add(foreign_tbl_name); + } + if (parent_db_name != null) { + params.add(foreign_db_name); + } + if (params.size() == 0) { + constraints = (Collection<?>) query.execute(); + } else { + constraints = (Collection<?>) query.executeWithArray(params); + } + pm.retrieveAll(constraints); + foreignKeys = new ArrayList<SQLForeignKey>(); + for (Iterator<?> i = constraints.iterator(); i.hasNext();) { + MConstraint currPKFK = (MConstraint) i.next(); + int enableValidateRely = currPKFK.getEnableValidateRely(); + boolean enable = (enableValidateRely & 4) != 0; + boolean validate = (enableValidateRely & 2) != 0; + boolean rely = (enableValidateRely & 1) != 0; + String consolidatedtblName = + currPKFK.getParentTable().getDatabase().getName() + "." + + currPKFK.getParentTable().getTableName(); + String pkName; + if (tblToConstraint.containsKey(consolidatedtblName)) { + pkName = tblToConstraint.get(consolidatedtblName); + } else { + pkName = getPrimaryKeyConstraintName(currPKFK.getParentTable().getDatabase().getName(), + currPKFK.getParentTable().getDatabase().getName()); + tblToConstraint.put(consolidatedtblName, pkName); + } + foreignKeys.add(new SQLForeignKey( + currPKFK.getParentTable().getDatabase().getName(), + currPKFK.getParentTable().getDatabase().getName(), + currPKFK.getParentColumn().getCols().get(0).getName(), + currPKFK.getChildTable().getDatabase().getName(), + currPKFK.getChildTable().getTableName(), + currPKFK.getChildColumn().getCols().get(0).getName(), + currPKFK.getPosition(), + currPKFK.getUpdateRule(), + currPKFK.getDeleteRule(), + currPKFK.getConstraintName(), pkName, enable, validate, rely)); + } + commited = commitTransaction(); + } finally { + if (!commited) { + rollbackTransaction(); + } + if (query != null) { + query.closeAll(); + } + } + return foreignKeys; + } + } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java index e49f757..100c396 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/RawStore.java @@ -51,6 +51,8 @@ import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; import org.apache.hadoop.hive.metastore.api.Type; @@ -663,4 +665,14 @@ public interface RawStore extends Configurable { @InterfaceStability.Evolving long getChangeVersion(String topic) throws MetaException; + + public abstract List<SQLPrimaryKey> getPrimaryKeys(String db_name, + String tbl_name) throws MetaException; + + public abstract List<SQLForeignKey> getForeignKeys(String parent_db_name, + String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) + throws MetaException; + + void createTableWithConstraints(Table tbl, List<SQLPrimaryKey> primaryKeys, + List<SQLForeignKey> foreignKeys) throws InvalidObjectException, MetaException; } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/java/org/apache/hadoop/hive/metastore/hbase/HBaseStore.java ---------------------------------------------------------------------- diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/hbase/HBaseStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/hbase/HBaseStore.java index a73dbeb..d4e5da4 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/hbase/HBaseStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/hbase/HBaseStore.java @@ -63,6 +63,8 @@ import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo; import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; import org.apache.hadoop.hive.metastore.api.Type; @@ -2591,4 +2593,26 @@ public class HBaseStore implements RawStore { commitOrRoleBack(commit); } } + + @Override + public List<SQLPrimaryKey> getPrimaryKeys(String db_name, String tbl_name) + throws MetaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<SQLForeignKey> getForeignKeys(String parent_db_name, + String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) + throws MetaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void createTableWithConstraints(Table tbl, + List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) + throws InvalidObjectException, MetaException { + // TODO Auto-generated method stub + } } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/model/org/apache/hadoop/hive/metastore/model/MConstraint.java ---------------------------------------------------------------------- diff --git a/metastore/src/model/org/apache/hadoop/hive/metastore/model/MConstraint.java b/metastore/src/model/org/apache/hadoop/hive/metastore/model/MConstraint.java new file mode 100644 index 0000000..3806e28 --- /dev/null +++ b/metastore/src/model/org/apache/hadoop/hive/metastore/model/MConstraint.java @@ -0,0 +1,148 @@ +package org.apache.hadoop.hive.metastore.model; + +import java.io.Serializable; + +public class MConstraint +{ + String constraintName; + int constraintType; + int position; + Integer deleteRule; + Integer updateRule; + MTable parentTable; + MTable childTable; + MColumnDescriptor parentColumn; + MColumnDescriptor childColumn; + int enableValidateRely; + + // 0 - Primary Key + // 1 - PK-FK relationship + public final static int PRIMARY_KEY_CONSTRAINT = 0; + public final static int FOREIGN_KEY_CONSTRAINT = 1; + + @SuppressWarnings("serial") + public static class PK implements Serializable { + public String constraintName; + public int position; + + public PK() {} + + public PK(String constraintName, int position) { + this.constraintName = constraintName; + this.position = position; + } + + public String toString() { + return constraintName+":"+position; + } + + public int hashCode() { + return toString().hashCode(); + } + + public boolean equals(Object other) { + if (other != null && (other instanceof PK)) { + PK otherPK = (PK) other; + return otherPK.constraintName.equals(constraintName) && otherPK.position == position; + } + return false; + } + } + + public MConstraint() {} + + public MConstraint(String constraintName, int constraintType, int position, Integer deleteRule, Integer updateRule, int enableRelyValidate, MTable parentTable, + MTable childTable, MColumnDescriptor parentColumn, + MColumnDescriptor childColumn) { + this.constraintName = constraintName; + this.constraintType = constraintType; + this.parentColumn = parentColumn; + this.parentTable = parentTable; + this.childColumn = childColumn; + this.childTable = childTable; + this.position = position; + this.deleteRule = deleteRule; + this.updateRule = updateRule; + this.enableValidateRely = enableRelyValidate; + } + + public String getConstraintName() { + return constraintName; + } + + public void setConstraintName(String fkName) { + this.constraintName = fkName; + } + + public int getConstraintType() { + return constraintType; + } + + public void setConstraintType(int ct) { + this.constraintType = ct; + } + + public int getPosition() { + return position; + } + + public void setPosition(int po) { + this.position = po; + } + + public Integer getDeleteRule() { + return deleteRule; + } + + public void setDeleteRule(Integer de) { + this.deleteRule = de; + } + + public int getEnableValidateRely() { + return enableValidateRely; + } + + public void setEnableValidateRely(int enableValidateRely) { + this.enableValidateRely = enableValidateRely; + } + + public Integer getUpdateRule() { + return updateRule; + } + + public void setUpdateRule(Integer ur) { + this.updateRule = ur; + } + + public MTable getChildTable() { + return childTable; + } + + public void setChildTable(MTable ft) { + this.childTable = ft; + } + + public MTable getParentTable() { + return parentTable; + } + + public void setParentTable(MTable pt) { + this.parentTable = pt; + } + + public MColumnDescriptor getChildColumn() { + return childColumn; + } + + public void setChildColumn(MColumnDescriptor cc) { + this.childColumn = cc; + } + + public MColumnDescriptor getParentColumn() { + return parentColumn; + } + + public void setParentColumn(MColumnDescriptor pc) { + this.parentColumn = pc; + } +} http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/model/package.jdo ---------------------------------------------------------------------- diff --git a/metastore/src/model/package.jdo b/metastore/src/model/package.jdo index 7385a13..b40df39 100644 --- a/metastore/src/model/package.jdo +++ b/metastore/src/model/package.jdo @@ -184,6 +184,39 @@ </field> </class> + <class name="MConstraint" identity-type="application" table="KEY_CONSTRAINTS" detachable="true" objectid-class="MConstraint$PK"> + <field name="constraintName" primary-key="true"> + <column name="CONSTRAINT_NAME"/> + </field> + <field name="position" primary-key="true"> + <column name="POSITION"/> + </field> + <field name="childColumn"> + <column name="CHILD_CD_ID"/> + </field> + <field name="childTable"> + <column name="CHILD_TBL_ID"/> + </field> + <field name="parentColumn"> + <column name="PARENT_CD_ID"/> + </field> + <field name="parentTable"> + <column name="PARENT_TBL_ID"/> + </field> + <field name="constraintType"> + <column name="CONSTRAINT_TYPE"/> + </field> + <field name="deleteRule"> + <column name="DELETE_RULE"/> + </field> + <field name="updateRule"> + <column name="UPDATE_RULE"/> + </field> + <field name="enableValidateRely"> + <column name="ENABLE_VALIDATE_RELY"/> + </field> + </class> + <class name="MSerDeInfo" identity-type="datastore" table="SERDES" detachable="true"> <datastore-identity> <column name="SERDE_ID"/> http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java ---------------------------------------------------------------------- diff --git a/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java b/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java index 94ca835..86e7bea 100644 --- a/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java +++ b/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java @@ -49,6 +49,8 @@ import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; import org.apache.hadoop.hive.metastore.api.Type; @@ -820,4 +822,26 @@ public class DummyRawStoreControlledCommit implements RawStore, Configurable { public long getChangeVersion(String topic) throws MetaException { return 0; } + + @Override + public List<SQLPrimaryKey> getPrimaryKeys(String db_name, String tbl_name) + throws MetaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<SQLForeignKey> getForeignKeys(String parent_db_name, + String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) + throws MetaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void createTableWithConstraints(Table tbl, + List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) + throws InvalidObjectException, MetaException { + // TODO Auto-generated method stub + } } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java ---------------------------------------------------------------------- diff --git a/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java b/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java index b108f95..5b32f00 100644 --- a/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java +++ b/metastore/src/test/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java @@ -50,6 +50,8 @@ import org.apache.hadoop.hive.metastore.api.PrincipalType; import org.apache.hadoop.hive.metastore.api.PrivilegeBag; import org.apache.hadoop.hive.metastore.api.Role; import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant; +import org.apache.hadoop.hive.metastore.api.SQLForeignKey; +import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; import org.apache.hadoop.hive.metastore.api.Type; @@ -836,6 +838,28 @@ public class DummyRawStoreForJdoConnection implements RawStore { public long getChangeVersion(String topic) throws MetaException { return 0; } + + @Override + public List<SQLPrimaryKey> getPrimaryKeys(String db_name, String tbl_name) + throws MetaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public List<SQLForeignKey> getForeignKeys(String parent_db_name, + String parent_tbl_name, String foreign_db_name, String foreign_tbl_name) + throws MetaException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void createTableWithConstraints(Table tbl, + List<SQLPrimaryKey> primaryKeys, List<SQLForeignKey> foreignKeys) + throws InvalidObjectException, MetaException { + // TODO Auto-generated method stub + } } http://git-wip-us.apache.org/repos/asf/hive/blob/55375ec1/service/src/gen/thrift/gen-py/hive_service/ThriftHive-remote ---------------------------------------------------------------------- diff --git a/service/src/gen/thrift/gen-py/hive_service/ThriftHive-remote b/service/src/gen/thrift/gen-py/hive_service/ThriftHive-remote index 9a2322f..4dfa83d 100755 --- a/service/src/gen/thrift/gen-py/hive_service/ThriftHive-remote +++ b/service/src/gen/thrift/gen-py/hive_service/ThriftHive-remote @@ -51,6 +51,7 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help': print(' get_schema_with_environment_context(string db_name, string table_name, EnvironmentContext environment_context)') print(' void create_table(Table tbl)') print(' void create_table_with_environment_context(Table tbl, EnvironmentContext environment_context)') + print(' void create_table_with_constraints(Table tbl, primaryKeys, foreignKeys)') print(' void drop_table(string dbname, string name, bool deleteData)') print(' void drop_table_with_environment_context(string dbname, string name, bool deleteData, EnvironmentContext environment_context)') print(' get_tables(string db_name, string pattern)') @@ -110,6 +111,8 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help': print(' Index get_index_by_name(string db_name, string tbl_name, string index_name)') print(' get_indexes(string db_name, string tbl_name, i16 max_indexes)') print(' get_index_names(string db_name, string tbl_name, i16 max_indexes)') + print(' PrimaryKeysResponse get_primary_keys(PrimaryKeysRequest request)') + print(' ForeignKeysResponse get_foreign_keys(ForeignKeysRequest request)') print(' bool update_table_column_statistics(ColumnStatistics stats_obj)') print(' bool update_partition_column_statistics(ColumnStatistics stats_obj)') print(' ColumnStatistics get_table_column_statistics(string db_name, string tbl_name, string col_name)') @@ -407,6 +410,12 @@ elif cmd == 'create_table_with_environment_context': sys.exit(1) pp.pprint(client.create_table_with_environment_context(eval(args[0]),eval(args[1]),)) +elif cmd == 'create_table_with_constraints': + if len(args) != 3: + print('create_table_with_constraints requires 3 args') + sys.exit(1) + pp.pprint(client.create_table_with_constraints(eval(args[0]),eval(args[1]),eval(args[2]),)) + elif cmd == 'drop_table': if len(args) != 3: print('drop_table requires 3 args') @@ -761,6 +770,18 @@ elif cmd == 'get_index_names': sys.exit(1) pp.pprint(client.get_index_names(args[0],args[1],eval(args[2]),)) +elif cmd == 'get_primary_keys': + if len(args) != 1: + print('get_primary_keys requires 1 args') + sys.exit(1) + pp.pprint(client.get_primary_keys(eval(args[0]),)) + +elif cmd == 'get_foreign_keys': + if len(args) != 1: + print('get_foreign_keys requires 1 args') + sys.exit(1) + pp.pprint(client.get_foreign_keys(eval(args[0]),)) + elif cmd == 'update_table_column_statistics': if len(args) != 1: print('update_table_column_statistics requires 1 args')
