Index: common/src/java/org/apache/hadoop/hive/common/VersionInfo.java =================================================================== --- common/src/java/org/apache/hadoop/hive/common/VersionInfo.java (revision 0) +++ common/src/java/org/apache/hadoop/hive/common/VersionInfo.java (revision 0) @@ -0,0 +1,99 @@ +/* + * 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.hadoop.hive.common; + +import org.apache.hadoop.hive.HiveVersionAnnotation; + +/** + * This class finds the package info for Hadoop and the HiveVersionAnnotation + * information. + */ +public class VersionInfo { + private static Package myPackage; + private static HiveVersionAnnotation version; + + static { + myPackage = HiveVersionAnnotation.class.getPackage(); + version = myPackage.getAnnotation(HiveVersionAnnotation.class); + } + + /** + * Get the meta-data for the Hive package. + * @return + */ + static Package getPackage() { + return myPackage; + } + + /** + * Get the Hive version. + * @return the Hive version string, eg. "0.6.0-dev" + */ + public static String getVersion() { + return version != null ? version.version() : "Unknown"; + } + + /** + * Get the subversion revision number for the root directory + * @return the revision number, eg. "451451" + */ + public static String getRevision() { + return version != null ? version.revision() : "Unknown"; + } + + /** + * The date that Hive was compiled. + * @return the compilation date in unix date format + */ + public static String getDate() { + return version != null ? version.date() : "Unknown"; + } + + /** + * The user that compiled Hive. + * @return the username of the user + */ + public static String getUser() { + return version != null ? version.user() : "Unknown"; + } + + /** + * Get the subversion URL for the root Hive directory. + */ + public static String getUrl() { + return version != null ? version.url() : "Unknown"; + } + + /** + * Returns the buildVersion which includes version, + * revision, user and date. + */ + public static String getBuildVersion(){ + return VersionInfo.getVersion() + + " from " + VersionInfo.getRevision() + + " by " + VersionInfo.getUser() + + " on " + VersionInfo.getDate(); + } + + public static void main(String[] args) { + System.out.println("Hive " + getVersion()); + System.out.println("Subversion " + getUrl() + " -r " + getRevision()); + System.out.println("Compiled by " + getUser() + " on " + getDate()); + } +} Index: common/src/java/org/apache/hadoop/hive/HiveVersionAnnotation.java =================================================================== --- common/src/java/org/apache/hadoop/hive/HiveVersionAnnotation.java (revision 0) +++ common/src/java/org/apache/hadoop/hive/HiveVersionAnnotation.java (revision 0) @@ -0,0 +1,56 @@ +/* + * 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.hadoop.hive; + +import java.lang.annotation.*; + +/** + * A package attribute that captures the version of Hive that was compiled. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PACKAGE) +public @interface HiveVersionAnnotation { + + /** + * Get the Hive version + * @return the version string "0.6.3-dev" + */ + String version(); + + /** + * Get the username that compiled Hive. + */ + String user(); + + /** + * Get the date when Hive was compiled. + * @return the date in unix 'date' format + */ + String date(); + + /** + * Get the url for the subversion repository. + */ + String url(); + + /** + * Get the subversion revision. + * @return the revision number as a string (eg. "451451") + */ + String revision(); +} Index: common/src/saveVersion.sh =================================================================== --- common/src/saveVersion.sh (revision 0) +++ common/src/saveVersion.sh (revision 0) @@ -0,0 +1,47 @@ +#!/bin/sh + +# 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. + + +# This file is used to generate the package-info.java class that +# records the version, revision, user, date and svn/git url. +unset LANG +unset LC_CTYPE +version=$1 +build=$2 +user=`whoami` +date=`date` +if [ -d .git ]; then + revision=`git log -1 --pretty=format:"%H"` + hostname=`hostname` + branch=`git branch | sed -n -e 's/^* //p'` + url="git://$hostname/$cwd on branch $branch" +else + revision=`svn info | sed -n -e 's/Last Changed Rev: \(.*\)/\1/p'` + url=`svn info | sed -n -e 's/URL: \(.*\)/\1/p'` +fi +mkdir -p $build/common/gen-java/org/apache/hadoop/hive +cat << EOF | \ + sed -e "s/VERSION/$version/" -e "s/USER/$user/" -e "s/DATE/$date/" \ + -e "s|URL|$url|" -e "s/REV/$revision/" \ + > $build/common/gen-java/org/apache/hadoop/hive/package-info.java +/* + * Generated by common/src/saveVersion.sh + */ +@HiveVersionAnnotation(version="VERSION", revision="REV", + user="USER", date="DATE", url="URL") +package org.apache.hadoop.hive; +EOF Property changes on: common/src/saveVersion.sh ___________________________________________________________________ Added: svn:executable + * Index: common/build.xml =================================================================== --- common/build.xml (revision 915190) +++ common/build.xml (working copy) @@ -24,9 +24,18 @@ --> - + + + + + + + + + + Index: ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java (revision 915190) +++ ql/src/java/org/apache/hadoop/hive/ql/QueryPlan.java (working copy) @@ -34,6 +34,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hive.common.VersionInfo; import org.apache.hadoop.hive.ql.exec.ConditionalTask; import org.apache.hadoop.hive.ql.exec.ExecDriver; import org.apache.hadoop.hive.ql.exec.FetchTask; @@ -60,6 +61,22 @@ private static final Log LOG = LogFactory.getLog(QueryPlan.class.getName()); + /** + * The version of the build. This gets changed in every build. + * We use this to verify that a query plan is generated by the same version + * of the code or not. + */ + private String buildVersion; + + /** + * Returns whether the query plan is generated by the same version of the code. + * We don't allow execution of a query plan generated by an earlier version of + * the code. + */ + public boolean isFromTheSameBuildVersion() { + return VersionInfo.getBuildVersion().equals(buildVersion); + } + private String queryString; private ArrayList> rootTasks; @@ -86,6 +103,7 @@ } public QueryPlan(String queryString, BaseSemanticAnalyzer sem) { + this.buildVersion = VersionInfo.getBuildVersion(); this.queryString = queryString; rootTasks = new ArrayList>(); @@ -711,4 +729,12 @@ this.started = started; } + public String getBuildVersion() { + return buildVersion; + } + + public void setBuildVersion(String buildVersion) { + this.buildVersion = buildVersion; + } + } Index: ql/src/java/org/apache/hadoop/hive/ql/parse/IllegalVersionException.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/parse/IllegalVersionException.java (revision 0) +++ ql/src/java/org/apache/hadoop/hive/ql/parse/IllegalVersionException.java (revision 0) @@ -0,0 +1,14 @@ +package org.apache.hadoop.hive.ql.parse; + +import org.apache.hadoop.hive.ql.metadata.HiveException; + +/** + * Exception for incompatible version of compiled query plan and the code. + */ +public class IllegalVersionException extends HiveException { + + public IllegalVersionException(String planVersion, String codeVersion) { + super("query plan is from \"" + planVersion + "\", code is from \"" + codeVersion + "\""); + } + +} Index: ql/src/java/org/apache/hadoop/hive/ql/Driver.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/Driver.java (revision 915190) +++ ql/src/java/org/apache/hadoop/hive/ql/Driver.java (working copy) @@ -37,6 +37,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.common.JavaUtils; +import org.apache.hadoop.hive.common.VersionInfo; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.MetaStoreUtils; import org.apache.hadoop.hive.metastore.api.FieldSchema; @@ -56,6 +57,7 @@ import org.apache.hadoop.hive.ql.parse.ASTNode; import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer; import org.apache.hadoop.hive.ql.parse.ErrorMsg; +import org.apache.hadoop.hive.ql.parse.IllegalVersionException; import org.apache.hadoop.hive.ql.parse.ParseDriver; import org.apache.hadoop.hive.ql.parse.ParseException; import org.apache.hadoop.hive.ql.parse.ParseUtils; @@ -336,6 +338,13 @@ // Use the deserialized plan plan = newPlan; + // Check plan's build version. + // It should be always true right now, but it won't be when we split the call to compile + // and execute. + if (!plan.isFromTheSameBuildVersion()) { + throw new IllegalVersionException(plan.getBuildVersion(), VersionInfo.getBuildVersion()); + } + // initialize FetchTask right here if (plan.getFetchTask() != null) { plan.getFetchTask().initialize(conf, plan, null); @@ -354,6 +363,12 @@ console.printError(errorMessage, "\n" + org.apache.hadoop.util.StringUtils.stringifyException(e)); return (11); + } catch (IllegalVersionException e) { + errorMessage = "FAILED: Version mismatch: " + e.getMessage(); + SQLState = ErrorMsg.findSQLState(e.getMessage()); + console.printError(errorMessage, "\n" + + org.apache.hadoop.util.StringUtils.stringifyException(e)); + return (13); } catch (Exception e) { errorMessage = "FAILED: Unknown exception: " + e.getMessage(); SQLState = ErrorMsg.findSQLState(e.getMessage());