I am attaching the patch here. Let me know if you have any comments.

I will also be adding more test cases with my next patch.

Satheesh

Satheesh Bandaram wrote:
Hi

I am attaching a patch that adds SYNONYM support to Derby.  Synonym provides an alternate name for a table or a view that is present in the same schema or another schema. A synonym can also be created for another synonym, causing nesting of synonyms. A synonym can be used in SELECT, INSERT, UPDATE, DELETE or LOCK TABLE statements instead of the original qualified table or view name. Note that a synonym can be created for a table or a view that doesn't yet exists. But the target table/view must be present before the synonym can be used.

Synonyms are supported by all major database vendors, including Oracle, DB2 and mySQL. DB2 also allows CREATE ALIAS statement, which does exactly same as CREATE SYNONYM. Creating aliases instead of synonyms is not supported by Oracle or mySQL, so I propose that Derby not support creating aliases. Synonyms are not part of SQL-2003 spec, but is a common-SQL statement among major database vendors. SQL standard doesn't pay attention to DDLs as much, so I suspect they skipped synonyms. We all know and love CREATE INDEX statement, which is also not part of the standard.

This current patch leaves out some changes that are needed. I will submit these in another patch:
  1. dblook changes. This schema generating tool needs to be modified to emit synonym information in the catalog.
  2. Registering and enforcing dependencies. Droping a synonym, for example, should invalidate all cached plans that use them. This is achieved by registering and enforcing dependencies using DependencyManager.
Let me know if you have any comments or suggestions. My vote is +1, to accept this patch.

Satheesh

[bandaram:satheesh] svn stat
M      java\engine\org\apache\derby\impl\sql\compile\NodeFactoryImpl.java
M      java\engine\org\apache\derby\impl\sql\compile\DropAliasNode.java
M      java\engine\org\apache\derby\impl\sql\compile\QueryTreeNode.java
M      java\engine\org\apache\derby\impl\sql\compile\CreateTableNode.java
M      java\engine\org\apache\derby\impl\sql\compile\LockTableNode.java
M      java\engine\org\apache\derby\impl\sql\compile\FromBaseTable.java
M      java\engine\org\apache\derby\impl\sql\compile\DMLModStatementNode.java
M      java\engine\org\apache\derby\impl\sql\compile\CreateAliasNode.java
M      java\engine\org\apache\derby\impl\sql\compile\sqlgrammar.jj
M      java\engine\org\apache\derby\impl\sql\compile\CreateViewNode.java
M      java\engine\org\apache\derby\impl\sql\execute\DropAliasConstantAction.java
M      java\engine\org\apache\derby\impl\sql\execute\CreateAliasConstantAction.java
M      java\engine\org\apache\derby\impl\sql\catalog\SYSALIASESRowFactory.java
M      java\engine\org\apache\derby\iapi\sql\compile\NodeFactory.java
M      java\engine\org\apache\derby\iapi\sql\dictionary\AliasDescriptor.java
M      java\engine\org\apache\derby\iapi\services\io\RegisteredFormatIds.java
M      java\engine\org\apache\derby\iapi\services\io\StoredFormatIds.java
M      java\engine\org\apache\derby\iapi\reference\SQLState.java
M      java\engine\org\apache\derby\catalog\AliasInfo.java
A      java\engine\org\apache\derby\catalog\types\SynonymAliasInfo.java
M      java\engine\org\apache\derby\loc\messages_en.properties
M      java\testing\org\apache\derbyTesting\functionTests\tests\lang\copyfiles.ant
A      java\testing\org\apache\derbyTesting\functionTests\tests\lang\synonym.sql
A      java\testing\org\apache\derbyTesting\functionTests\master\synonym.out
[bandaram:satheesh]
Index: java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java  
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java  
(working copy)
@@ -596,7 +596,7 @@
        public  QueryTreeNode
        getCreateAliasNode(
                Object aliasName,
-               String fullStaticMethodName,
+               Object targetName,
                Object aliasSpecificInfo,
                char aliasType,
                Boolean delimitedIdentifier,
@@ -605,37 +605,39 @@
        {
                int nodeType;
                String methodName = null;
-               String javaClassName = fullStaticMethodName;
                String targetMethodName = null;
                String targetClassName = null;
 
                nodeType = C_NodeTypes.CREATE_ALIAS_NODE;
 
-        int lastPeriod;
-        int paren = fullStaticMethodName.indexOf('(');
-        if (paren == -1) {
-            // not a Java signature - split based on last period
-            lastPeriod = fullStaticMethodName.lastIndexOf('.');
-        } else {
-            // a Java signature - split on last period before the '('
-            lastPeriod = fullStaticMethodName.substring(0, 
paren).lastIndexOf('.');
-        }
-        if (lastPeriod == -1 || lastPeriod == fullStaticMethodName.length()-1) 
{
-            throw 
StandardException.newException(SQLState.LANG_INVALID_FULL_STATIC_METHOD_NAME, 
fullStaticMethodName);
-        }
-        javaClassName = fullStaticMethodName.substring(0, lastPeriod);
-        methodName = fullStaticMethodName.substring(lastPeriod + 1);
+               if (aliasType != AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR)
+               {
+               int lastPeriod;
+               String fullStaticMethodName = (String) targetName;
+               int paren = fullStaticMethodName.indexOf('(');
+               if (paren == -1) {
+               // not a Java signature - split based on last period
+               lastPeriod = fullStaticMethodName.lastIndexOf('.');
+               } else {
+               // a Java signature - split on last period before the '('
+               lastPeriod = fullStaticMethodName.substring(0, 
paren).lastIndexOf('.');
+               }
+               if (lastPeriod == -1 || lastPeriod == 
fullStaticMethodName.length()-1) {
+               throw 
StandardException.newException(SQLState.LANG_INVALID_FULL_STATIC_METHOD_NAME, 
fullStaticMethodName);
+               }
+               String javaClassName = fullStaticMethodName.substring(0, 
lastPeriod);
+               methodName = fullStaticMethodName.substring(lastPeriod + 1);
+                       targetName = javaClassName;
+               }
 
                return getNode(
                        nodeType,
                        aliasName,
-                       javaClassName,
+                       targetName,
                        methodName,
                        aliasSpecificInfo,
                        new Character(aliasType),
                        delimitedIdentifier,
                        cm );
        }
-
-
 }
Index: java/engine/org/apache/derby/impl/sql/compile/DropAliasNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/DropAliasNode.java    
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/DropAliasNode.java    
(working copy)
@@ -75,6 +75,10 @@
                                nameSpace = 
AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR;
                                break;
 
+                       case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                               nameSpace = 
AliasInfo.ALIAS_NAME_SPACE_SYNONYM_AS_CHAR;
+                               break;
+
                        default:
                                if (SanityManager.DEBUG)
                                {
@@ -149,6 +153,9 @@
                        case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
                                typeName = "FUNCTION";
                                break;
+                       case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                               typeName = "SYNONYM";
+                               break;
                }
                return typeName;
        }
Index: java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java    
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java    
(working copy)
@@ -46,6 +46,7 @@
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.sql.execute.ConstantAction;
@@ -60,6 +61,7 @@
 import org.apache.derby.iapi.sql.depend.DependencyManager;
 import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
 import org.apache.derby.catalog.AliasInfo;
+import org.apache.derby.catalog.types.SynonymAliasInfo;
 import java.util.Properties;
 import java.util.Vector;
 import java.sql.Types;
@@ -1470,6 +1472,46 @@
        }
 
        /**
+        * Resolve table/view reference to a synonym. May have to follow a 
synonym chain.
+        *
+        * @param       tabName to match for a synonym
+        *
+        * @return      Synonym TableName if a match is found, NULL otherwise.
+        *
+        * @exception StandardException         Thrown on error
+        */
+       public TableName resolveTableToSynonym(TableName tabName) throws 
StandardException
+       {
+               DataDictionary dd = getDataDictionary();
+               String nextSynonymTable = tabName.getTableName();
+               String nextSynonymSchema = tabName.getSchemaName();
+               boolean found = false;
+               for (;;)
+               {
+                       SchemaDescriptor nextSD = 
getSchemaDescriptor(nextSynonymSchema, false);
+                       if (nextSD == null || nextSD.getUUID() == null)
+                               break;
+       
+                       AliasDescriptor nextAD = 
dd.getAliasDescriptor(nextSD.getUUID().toString(),
+                                                nextSynonymTable, 
AliasInfo.ALIAS_NAME_SPACE_SYNONYM_AS_CHAR);
+                       if (nextAD == null)
+                               break;
+
+                       found = true;
+                       SynonymAliasInfo info = 
((SynonymAliasInfo)nextAD.getAliasInfo());
+                       nextSynonymTable = info.getSynonymTable();
+                       nextSynonymSchema = info.getSynonymSchema();
+               }
+
+               if (!found)
+                       return null;
+
+               TableName tableName = new TableName();
+               tableName.init(nextSynonymSchema, nextSynonymTable);
+               return tableName;
+       }
+
+       /**
         * 
         * @param javaClassName The name of the java class to resolve.
         *
Index: java/engine/org/apache/derby/impl/sql/compile/CreateTableNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/CreateTableNode.java  
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/CreateTableNode.java  
(working copy)
@@ -211,6 +211,11 @@
 
                tableElementList.validate(this, dataDictionary, 
(TableDescriptor) null);
 
+               if (resolveTableToSynonym(getObjectName()) != null)
+                       throw 
StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS,
+                                                               "Synonym",
+                                                               
getObjectName().toString());
+
                /* Only 1012 columns allowed per table */
                if (tableElementList.countNumberOfColumns() > 
Limits.DB2_MAX_COLUMNS_IN_TABLE)
                {
Index: java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java       
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java       
(working copy)
@@ -201,6 +201,11 @@
 
                DataDictionary dataDictionary = getDataDictionary();
 
+               // check if targetTable is a synonym
+               TableName synonymTab = 
resolveTableToSynonym(this.targetTableName);
+               if (synonymTab != null)
+                       this.targetTableName = synonymTab;
+
                bindTables(dataDictionary);
 
                // wait to bind named target table until the cursor
Index: java/engine/org/apache/derby/impl/sql/compile/LockTableNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/LockTableNode.java    
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/LockTableNode.java    
(working copy)
@@ -130,7 +130,16 @@
 
                if (lockTableDescriptor == null)
                {
-                       throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
+                       // Check if the reference is for a synonym.
+                       TableName synonymTab = resolveTableToSynonym(tableName);
+                       if (synonymTab == null)
+                               throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
+                       tableName = synonymTab;
+                       sd = getSchemaDescriptor(tableName.getSchemaName());
+
+                       lockTableDescriptor = 
getTableDescriptor(synonymTab.getTableName(), sd);
+                       if (lockTableDescriptor == null)
+                               throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
                }
 
                //throw an exception if user is attempting to lock a temporary 
table
Index: java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java    
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java    
(working copy)
@@ -2369,7 +2369,16 @@
                }
                else
                {
-                       throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
+                       // Check if the reference is for a synonym.
+                       TableName synonymTab = resolveTableToSynonym(tableName);
+                       if (synonymTab == null)
+                               throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
+                       tableName = synonymTab;
+                       sd = getSchemaDescriptor(tableName.getSchemaName());
+
+                       tableDescriptor = 
getTableDescriptor(synonymTab.getTableName(), sd);
+                       if (tableDescriptor == null)
+                               throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
                }
 
                return  tableDescriptor;
Index: java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java      
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java      
(working copy)
@@ -215,16 +215,23 @@
                        /*
                        ** Get the TableDescriptor for the table we are 
inserting into
                        */
-                       String sntc = targetTableName.getSchemaName();
+                       SchemaDescriptor sdtc = 
getSchemaDescriptor(targetTableName.getSchemaName());
 
-                       SchemaDescriptor sdtc = getSchemaDescriptor(sntc);
-
                        targetTableDescriptor = getTableDescriptor(
                                                        
targetTableName.getTableName(), sdtc);
 
                        if (targetTableDescriptor == null)
                        {
-                               throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName);
+                               // Check if the reference is for a synonym.
+                               TableName synonymTab = 
resolveTableToSynonym(targetTableName);
+                               if (synonymTab == null)
+                                       throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName);
+                               targetTableName = synonymTab;
+                               sdtc = 
getSchemaDescriptor(targetTableName.getSchemaName());
+
+                               targetTableDescriptor = 
getTableDescriptor(synonymTab.getTableName(), sdtc);
+                               if (targetTableDescriptor == null)
+                                       throw 
StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName);
                        }
 
                        // Views are currently not updatable */
Index: java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java  
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/CreateAliasNode.java  
(working copy)
@@ -36,6 +36,8 @@
 import org.apache.derby.iapi.types.TypeId;
 
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
 
 import org.apache.derby.iapi.error.StandardException;
 
@@ -48,6 +50,7 @@
 import org.apache.derby.catalog.AliasInfo;
 import org.apache.derby.catalog.TypeDescriptor;
 import org.apache.derby.catalog.types.RoutineAliasInfo;
+import org.apache.derby.catalog.types.SynonymAliasInfo;
 
 import java.lang.reflect.Member;
 import java.util.Vector;
@@ -72,7 +75,7 @@
         * Initializer for a CreateAliasNode
         *
         * @param aliasName                             The name of the alias
-        * @param javaClassName                 The full class name
+        * @param targetObject                  Target name
         * @param methodName                The method name
         * @param aliasType                             The alias type
         * @param delimitedIdentifier   Whether or not to treat the class name
@@ -83,7 +86,7 @@
         */
        public void init(
                                                Object aliasName,
-                                               Object javaClassName,
+                                               Object targetObject,
                                                Object methodName,
                                                Object aliasSpecificInfo,
                                                Object aliasType,
@@ -91,21 +94,20 @@
                throws StandardException
        {               
                TableName qn = (TableName) aliasName;
+               this.aliasType = ((Character) aliasType).charValue();
 
                initAndCheck(qn);
-                       
-               this.javaClassName = (String) javaClassName;
-               this.methodName = (String) methodName;
-               this.aliasType = ((Character) aliasType).charValue();
-               this.delimitedIdentifier =
-                                                               ((Boolean) 
delimitedIdentifier).booleanValue();
 
-
                switch (this.aliasType)
                {
                        case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
                        case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
                        {
+                               this.javaClassName = (String) targetObject;
+                               this.methodName = (String) methodName;
+                               this.delimitedIdentifier =
+                                                               ((Boolean) 
delimitedIdentifier).booleanValue();
+
                                //routineElements contains the description of 
the procedure.
                                // 
                                // 0 - Object[] 3 element array for parameters
@@ -197,6 +199,14 @@
                                }
                                break;
 
+                       case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                               String targetSchema;
+                               TableName t = (TableName) targetObject;
+                               if (t.getSchemaName() != null)
+                                       targetSchema = t.getSchemaName();
+                               else targetSchema = 
getSchemaDescriptor().getSchemaName();
+                               aliasInfo = new SynonymAliasInfo(targetSchema, 
t.getTableName());
+                               break;
 
                        default:
                                if (SanityManager.DEBUG)
@@ -213,6 +223,8 @@
                {
                case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
                        return "CREATE PROCEDURE";
+               case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                       return "CREATE SYNONYM";
                default:
                        return "CREATE FUNCTION";
                }
@@ -233,8 +245,27 @@
 
        public QueryTreeNode bind() throws StandardException
        {
-               // Procedures do not check class or method validity until 
runtime execution of the procedure.
+               // Procedures and functions do not check class or method 
validity until
+               // runtime execution. Synonyms do need some validity checks.
+               if (aliasType != AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR)
+                       return this;
 
+               String targetSchema = 
((SynonymAliasInfo)aliasInfo).getSynonymSchema();
+               String targetTable = 
((SynonymAliasInfo)aliasInfo).getSynonymTable();
+               if (this.getObjectName().equals(targetSchema, targetTable))
+                       throw 
StandardException.newException(SQLState.LANG_SYNONYM_REPETITIVE,
+                                               this.getFullName(),
+                                               targetSchema+"."+targetTable);
+
+               // Raise error if targetSchema doesn't exists
+               SchemaDescriptor targetSD = getSchemaDescriptor(targetSchema);
+
+               // Synonym can't be defined on temporary tables.
+               TableDescriptor targetTD = getTableDescriptor(targetTable, 
targetSD);
+               if (targetTD != null &&
+                       targetTD.getTableType() == 
TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
+                       throw 
StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
+
                return this;
        }
 
@@ -251,6 +282,9 @@
                case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
                        schemaName = getSchemaDescriptor().getSchemaName();
                        break;
+               case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                       schemaName = getSchemaDescriptor().getSchemaName();
+                       break;
                default:
                        schemaName = null;
                }
Index: java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (revision 
179354)
+++ java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (working copy)
@@ -1868,6 +1868,7 @@
 |      <SQL_TSI_YEAR: "sql_tsi_year">
 |      <START: "start">
 |      <STATEMENT: "statement">
+|      <SYNONYM: "synonym">
 |      <THEN: "then">
 |      <TIME: "time">
 |      <TIMESTAMP: "timestamp">
@@ -2413,7 +2414,8 @@
                (
             statementNode = schemaDefinition() |
             statementNode = viewDefinition(beginToken) |
-           statementNode = triggerDefinition()
+            statementNode = triggerDefinition() |
+            statementNode = synonymDefinition()
         )
         {
         }
@@ -9048,6 +9050,32 @@
        }
 }
 
+QueryTreeNode
+synonymDefinition() throws StandardException :
+{
+       TableName synonymName;
+       TableName targetName;
+}
+{
+    <SYNONYM> synonymName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) <FOR>
+                targetName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)
+       {
+               checkVersion(DataDictionary.DD_VERSION_DERBY_10_1,
+                            "CREATE SYNONYM");
+
+               return  (StatementNode) getNodeFactory().getCreateAliasNode
+                       (
+                               synonymName,
+                               targetName,
+                               null,
+                               AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR,
+                               Boolean.FALSE,
+                               getContextManager()
+                       );
+       }
+}
+
+
 Boolean
 beforeOrAfter() :
 {}
@@ -11044,6 +11072,12 @@
        {
                return dropAliasNode(aliasName, 
AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR);
        }  
+|      <SYNONYM> aliasName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)
+       {
+               checkVersion(DataDictionary.DD_VERSION_DERBY_10_1, "DROP 
SYNONYM");
+
+               return dropAliasNode(aliasName, 
AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR);
+       }
 }
 
 QueryTreeNode
@@ -11537,6 +11571,7 @@
     |       tok = <STABILITY>
        |       tok = <START>
        |       tok = <STATEMENT>
+       |       tok = <SYNONYM>
        |       tok = <STYLE>
        |       tok = <T>
        |       tok = <THEN>
Index: java/engine/org/apache/derby/impl/sql/compile/CreateViewNode.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/compile/CreateViewNode.java   
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/compile/CreateViewNode.java   
(working copy)
@@ -179,6 +179,11 @@
                ResultColumnList                        qeRCL;
                String                                          
duplicateColName;
 
+               if (resolveTableToSynonym(getObjectName()) != null)
+                       throw 
StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS,
+                                                               "Synonym",
+                                                               
getObjectName().toString());
+
                // bind the query expression
 
                providerInfos = bindViewDefinition
Index: 
java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java  
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java  
(working copy)
@@ -129,7 +129,7 @@
                // RESOLVE - fix error message
                if (ad == null)
                {
-                       throw 
StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "Method alias",  
aliasName);
+                       throw 
StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, 
ad.getAliasType(nameSpace),  aliasName);
                }
 
                /* Prepare all dependents to invalidate.  (This is their chance
Index: 
java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java
===================================================================
--- 
java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java    
    (revision 179354)
+++ 
java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java    
    (working copy)
@@ -26,6 +26,7 @@
 
 import org.apache.derby.iapi.sql.execute.ConstantAction;
 
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
@@ -48,6 +49,7 @@
 
 import org.apache.derby.catalog.AliasInfo;
 import org.apache.derby.catalog.types.RoutineAliasInfo;
+import org.apache.derby.catalog.types.SynonymAliasInfo;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -76,9 +78,7 @@
         *  @param aliasName            Name of alias.
         *  @param schemaName           Name of alias's schema.
         *  @param javaClassName        Name of java class.
-        *  @param methodName           Name of method.
-        *  @param targetClassName      Name of java class at Target database.
-        *  @param targetMethodName     Name of method at Target database.
+        *  @param aliasInfo            AliasInfo
         *  @param aliasType            The type of the alias
         */
        CreateAliasConstantAction(
@@ -103,6 +103,10 @@
                                nameSpace = 
AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR;
                                break;
 
+                       case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                               nameSpace = 
AliasInfo.ALIAS_NAME_SPACE_SYNONYM_AS_CHAR;
+                               break;
+
                        default:
                                if (SanityManager.DEBUG)
                                {
@@ -132,6 +136,10 @@
                                type = "CREATE FUNCTION ";
                                break;
 
+                       case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                               type = "CREATE SYNONYM ";
+                               break;
+
                        default:
                                if (SanityManager.DEBUG)
                                {
@@ -167,6 +175,7 @@
                                        (LanguageConnectionContext.CONTEXT_ID);
                }
                DataDictionary dd = lcc.getDataDictionary();
+               TransactionController tc = lcc.getTransactionExecute();
 
                /* Verify the method alias:
                **              Aggregates - just verify the class
@@ -176,7 +185,6 @@
                */
                String checkMethodName = null;
 
-                       
                String checkClassName = javaClassName;
 
                if (aliasInfo != null)
@@ -188,7 +196,9 @@
                {
                case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
                case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
+               case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
                        break;
+
                default:
                {
 
@@ -271,7 +281,7 @@
                                                                         false,
                                                                         
aliasInfo, null);
 
-               // perform duplicate rule checking for routine
+               // perform duplicate rule checking
                switch (aliasType) {
                case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
                case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
@@ -296,6 +306,48 @@
                        }
                }
                break;
+               case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                       // If target table/view exists already, error.
+                       TableDescriptor targetTD = 
dd.getTableDescriptor(aliasName, sd);
+                       if (targetTD != null)
+                       {
+                               throw StandardException.newException(
+                                                               
SQLState.LANG_OBJECT_ALREADY_EXISTS,
+                                                               
targetTD.getDescriptorType(),
+                                                               
targetTD.getDescriptorName());
+                       }
+
+                       // Detect synonym cycles, if present.
+                       String nextSynTable = 
((SynonymAliasInfo)aliasInfo).getSynonymTable();
+                       String nextSynSchema = 
((SynonymAliasInfo)aliasInfo).getSynonymSchema();
+                       SchemaDescriptor nextSD;
+                       for (;;)
+                       {
+                               nextSD = dd.getSchemaDescriptor(nextSynSchema, 
tc, false);
+                               if (nextSD == null)
+                                       break;
+                               
+                               AliasDescriptor nextAD = 
dd.getAliasDescriptor(nextSD.getUUID().toString(),
+                                                nextSynTable, nameSpace);
+                               if (nextAD == null)
+                                       break;
+
+                               SynonymAliasInfo info = (SynonymAliasInfo) 
nextAD.getAliasInfo();
+                               nextSynTable = info.getSynonymTable();
+                               nextSynSchema = info.getSynonymSchema();
+
+                               if (aliasName.equals(nextSynTable) && 
schemaName.equals(nextSynSchema))
+                                       throw 
StandardException.newException(SQLState.LANG_SYNONYM_REPETITIVE,
+                                                       aliasName, 
((SynonymAliasInfo)aliasInfo).getSynonymTable());
+                       }
+
+                       // If synonym final target is not present, raise a 
warning
+                       if (nextSD != null)
+                               targetTD = dd.getTableDescriptor(nextSynTable, 
nextSD);
+                       if (nextSD == null || targetTD == null)
+                               activation.addWarning(
+                                       
StandardException.newWarning(SQLState.LANG_SYNONYM_UNDEFINED,
+                                                               aliasName, 
nextSynSchema+"."+nextSynTable));
                default:
                        break;
                }
@@ -303,5 +355,4 @@
                dd.addDescriptor(ads, null, 
DataDictionary.SYSALIASES_CATALOG_NUM,
                                                 false, 
lcc.getTransactionExecute());
        }
-
 }
Index: java/engine/org/apache/derby/impl/sql/catalog/SYSALIASESRowFactory.java
===================================================================
--- java/engine/org/apache/derby/impl/sql/catalog/SYSALIASESRowFactory.java     
(revision 179354)
+++ java/engine/org/apache/derby/impl/sql/catalog/SYSALIASESRowFactory.java     
(working copy)
@@ -191,6 +191,7 @@
                                {
                                        case 
AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
                                        case 
AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
+                                       case 
AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
                                                break;
 
                                        default:
@@ -370,6 +371,7 @@
                        {
                                case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR: 
                                case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR: 
+                               case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR: 
                                        break;
 
                                default: 
@@ -391,6 +393,7 @@
                        {
                                case 
AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR: 
                                case 
AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR: 
+                               case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR: 
                                        break;
 
                                default: 
Index: java/engine/org/apache/derby/iapi/sql/compile/NodeFactory.java
===================================================================
--- java/engine/org/apache/derby/iapi/sql/compile/NodeFactory.java      
(revision 179354)
+++ java/engine/org/apache/derby/iapi/sql/compile/NodeFactory.java      
(working copy)
@@ -590,7 +590,7 @@
        public abstract QueryTreeNode
        getCreateAliasNode(
                Object aliasName,
-               String fullStaticMethodName,
+               Object targetName,
                Object aliasSpecificInfo,
                char aliasType,
                Boolean delimitedIdentifier,
Index: java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java
===================================================================
--- java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java       
(revision 179354)
+++ java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java       
(working copy)
@@ -288,17 +288,23 @@
        /** @see TupleDescriptor#getDescriptorType */
        public String getDescriptorType()
        {
-               switch (aliasType)
+               return getAliasType(aliasType);
+       }
+       
+       public static final String getAliasType(char nameSpace)
+       {
+               switch (nameSpace)
                {
                        case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
                                return "PROCEDURE";
                        case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
                                return "FUNCTION";
-                       default:
-                               return  null;
+                       case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
+                               return "SYNONYM";
                }
+               return  null;
        }
-       
+
        /** @see TupleDescriptor#getDescriptorName */
        public String getDescriptorName()
        {
Index: java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
===================================================================
--- java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java      
(revision 179354)
+++ java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java      
(working copy)
@@ -514,6 +514,7 @@
  
         /* 451 */   "org.apache.derby.catalog.types.RoutineAliasInfo",
                /* 452 */   null,
-               /* 453 */   
"org.apache.derby.impl.store.raw.log.ChecksumOperation"
+               /* 453 */   
"org.apache.derby.impl.store.raw.log.ChecksumOperation",
+               /* 454 */   "org.apache.derby.catalog.types.SynonymAliasInfo"
 };
 }
Index: java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
===================================================================
--- java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java  
(revision 179354)
+++ java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java  
(working copy)
@@ -1384,6 +1384,7 @@
 
 
        public static final int ROUTINE_INFO_V01_ID = (MIN_ID_2 + 451);
+       public static final int SYNONYM_INFO_V01_ID = (MIN_ID_2 + 454);
 
        /******************************************************************
        **
@@ -1806,7 +1807,7 @@
          * Make sure this is updated when a new module is added
          */
         public static final int MAX_ID_2 =
-                (MIN_ID_2 + 453);
+                (MIN_ID_2 + 454);
 
         // DO NOT USE 4 BYTE IDS ANYMORE
         static public final int MAX_ID_4 =
Index: java/engine/org/apache/derby/iapi/reference/SQLState.java
===================================================================
--- java/engine/org/apache/derby/iapi/reference/SQLState.java   (revision 
179354)
+++ java/engine/org/apache/derby/iapi/reference/SQLState.java   (working copy)
@@ -630,6 +630,7 @@
        String LANG_COL_NOT_NULL                                                
                                   = "01503";
        String LANG_INDEX_DUPLICATE                                             
                                   = "01504";
        String LANG_VALUE_TRUNCATED                                        = 
"01505";
+       String LANG_SYNONYM_UNDEFINED                                      = 
"01522";
        String LANG_NULL_ELIMINATED_IN_SET_FUNCTION                             
                   = "01003";
 
        String LANG_NO_ROW_FOUND                                                
                                   = "02000";
@@ -707,6 +708,7 @@
        String LANG_NO_AGGREGATES_IN_WHERE_CLAUSE                          = 
"42903";
        String LANG_DB2_VIEW_REQUIRES_COLUMN_NAMES                         = 
"42908";
        String LANG_DELETE_RULE_VIOLATION                                       
                       = "42915";
+       String LANG_SYNONYM_REPETITIVE                                          
                       = "42916";
        String LANG_DB2_ON_CLAUSE_INVALID                                       
                       = "42972";
        String LANG_SYNTAX_ERROR                                           = 
"42X01";
        String LANG_LEXICAL_ERROR                                          = 
"42X02";
Index: java/engine/org/apache/derby/catalog/AliasInfo.java
===================================================================
--- java/engine/org/apache/derby/catalog/AliasInfo.java (revision 179354)
+++ java/engine/org/apache/derby/catalog/AliasInfo.java (working copy)
@@ -28,6 +28,7 @@
  * <ul>
  * <li>method alias
  * <li>class alias
+ * <li>synonym
  * <li>user-defined aggregate
  * </ul>
  *
@@ -39,18 +40,22 @@
         */
        public static final char ALIAS_TYPE_PROCEDURE_AS_CHAR           = 'P';
        public static final char ALIAS_TYPE_FUNCTION_AS_CHAR            = 'F';
+       public static final char ALIAS_TYPE_SYNONYM_AS_CHAR             = 'S';  
 
        public static final String ALIAS_TYPE_PROCEDURE_AS_STRING               
= "P";
        public static final String ALIAS_TYPE_FUNCTION_AS_STRING                
= "F";
+       public static final String ALIAS_TYPE_SYNONYM_AS_STRING                 
= "S";
 
        /**
         * Public statics for the various alias name spaces as both char and 
String.
         */
        public static final char ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR     = 'P';
        public static final char ALIAS_NAME_SPACE_FUNCTION_AS_CHAR      = 'F';
+       public static final char ALIAS_NAME_SPACE_SYNONYM_AS_CHAR       = 'S';
 
        public static final String ALIAS_NAME_SPACE_PROCEDURE_AS_STRING = "P";
        public static final String ALIAS_NAME_SPACE_FUNCTION_AS_STRING  = "F";
+       public static final String ALIAS_NAME_SPACE_SYNONYM_AS_STRING   = "S";
 
        /**
         * Get the name of the static method that the alias 
Index: java/engine/org/apache/derby/catalog/types/SynonymAliasInfo.java
===================================================================
--- java/engine/org/apache/derby/catalog/types/SynonymAliasInfo.java    
(revision 0)
+++ java/engine/org/apache/derby/catalog/types/SynonymAliasInfo.java    
(revision 0)
@@ -0,0 +1,107 @@
+/*
+
+   Derby - Class org.apache.derby.catalog.types.SynonymAliasInfo
+
+   Copyright 2003, 2004 The Apache Software Foundation or its licensors, as 
applicable.
+
+   Licensed 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.derby.catalog.types;
+
+import org.apache.derby.iapi.services.io.Formatable;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.catalog.AliasInfo;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+/**
+ * Describe an S (Synonym) alias.
+ *
+ * @see AliasInfo
+ */
+public class SynonymAliasInfo implements AliasInfo, Formatable
+{
+       private String schemaName = null;
+       private String tableName = null;
+
+       public SynonymAliasInfo() {
+       }
+
+       /**
+               Create a SynonymAliasInfo for synonym.
+       */
+       public SynonymAliasInfo(String schemaName, String tableName)
+       {
+               this.schemaName = schemaName;
+               this.tableName = tableName;
+       }
+
+       public String getSynonymTable() {
+               return tableName;
+       }
+
+       public String getSynonymSchema() {
+               return schemaName;
+       }
+
+       // Formatable methods
+
+       /**
+        * Read this object from a stream of stored objects.
+        *
+        * @param in read this.
+        *
+        * @exception IOException                                       thrown 
on error
+        * @exception ClassNotFoundException            thrown on error
+        */
+       public void readExternal( ObjectInput in )
+                throws IOException, ClassNotFoundException
+       {
+               schemaName = (String) in.readObject();
+               tableName = (String) in.readObject();
+       }
+
+       /**
+        * Write this object to a stream of stored objects.
+        *
+        * @param out write bytes here.
+        *
+        * @exception IOException               thrown on error
+        */
+       public void writeExternal( ObjectOutput out )
+                throws IOException
+       {
+               out.writeObject(schemaName);
+               out.writeObject(tableName);
+       }
+ 
+       /**
+        * Get the formatID which corresponds to this class.
+        *
+        *      @return the formatID of this class
+        */
+       public  int     getTypeFormatId()       { return 
StoredFormatIds.SYNONYM_INFO_V01_ID; }
+
+       public String toString() {
+               return "SchemaLen:"+schemaName.length()+" 
"+schemaName+tableName;
+       }
+
+       public String getMethodName()
+       {
+               return null;
+       }
+}
+

Property changes on: 
java/engine/org/apache/derby/catalog/types/SynonymAliasInfo.java
___________________________________________________________________
Name: svn:eol-style
   + native

Index: java/engine/org/apache/derby/loc/messages_en.properties
===================================================================
--- java/engine/org/apache/derby/loc/messages_en.properties     (revision 
179354)
+++ java/engine/org/apache/derby/loc/messages_en.properties     (working copy)
@@ -351,6 +351,7 @@
 01503=The column {0} on table {1} has been modified by adding a not null 
constraint.
 01504=The new index is a duplicate of an existing index: {0}.
 01505=The value {0} may be truncated.
+01522=The newly defined alias ''{0}'' resolved to the object ''{1}'' which is 
currently undefined.
 01003=Null values were eliminated from the argument of a column function.
 0100E=XX Attepmt to return too many result sets
 02000=No row was found for FETCH, UPDATE or DELETE; or the result of a query 
is an empty table.
@@ -413,6 +414,7 @@
 42903=Invalid use of an aggregate function.
 42908=The CREATE VIEW statement does not include a column list.
 42915=Foreign  Key ''{0}'' is invalid because ''{1}''. 
+42916=Synonym ''{0}'' cannot be created for ''{1}'' as it would result in a 
repetitive synonym chain.
 42972=An ON clause associated with a JOIN operator is not valid.
 42X01=Syntax error: {0}.
 42X02={0}.
Index: 
java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant 
(revision 179354)
+++ java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant 
(working copy)
@@ -186,6 +186,7 @@
 supersimple.sql
 supersimple_derby.properties
 syscat.sql
+synonym.sql
 tempRestrictions.sql
 triggerBeforeTrig.sql
 triggerGeneral.sql
Index: java/testing/org/apache/derbyTesting/functionTests/tests/lang/synonym.sql
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/tests/lang/synonym.sql   
(revision 0)
+++ java/testing/org/apache/derbyTesting/functionTests/tests/lang/synonym.sql   
(revision 0)
@@ -0,0 +1,115 @@
+-- tests for synonym support
+
+set schema APP;
+-- negative tests
+-- Create a synonym to itself. Error.
+create synonym syn for syn;
+create synonym syn for APP.syn;
+create synonym APP.syn for syn;
+create synonym APP.syn for APP.syn;
+
+-- Create a simple synonym loop. Error.
+create synonym synonym1 for synonym;
+create synonym synonym for synonym1;
+drop synonym synonym1;
+
+-- Create a larger synonym loop.
+create synonym ts1 for ts;
+create synonym ts2 for ts1;
+create synonym ts3 for ts2;
+create synonym ts4 for ts3;
+create synonym ts5 for ts4;
+create synonym ts6 for ts5;
+create synonym ts for ts6;
+drop synonym App.ts1;
+drop synonym "APP".ts2;
+drop synonym TS3;
+drop synonym ts4;
+drop synonym ts5;
+drop synonym app.ts6;
+
+-- Synonyms and table/view share same namespace. Negative tests for this.
+create table table1 (i int, j int);
+insert into table1 values (1,1), (2,2);
+create view view1 as select i, j from table1;
+
+create synonym table1 for t1;
+create synonym APP.Table1 for t1;
+create synonym app.TABLE1 for "APP"."T";
+
+create synonym APP.VIEW1 for v1;
+create synonym "APP"."VIEW1" for app.v;
+
+-- Synonyms can't be created on temporary tables
+declare global temporary table session.t1 (c1 int) not logged;
+create synonym synForTemp for session.t1;
+create synonym synForTemp for session."T1";
+
+-- Creating a table or a view when a synonym of that name is present. Error.
+create synonym myTable for table1;
+
+create table myTable(i int, j int);
+
+create view myTable as select * from table1;
+
+
+-- Positive test cases
+
+-- Using synonym in DML
+
+select * from table1;
+select * from myTable;
+insert into myTable values (3,3), (4,4);
+
+select * from mytable;
+
+update myTable set i=3 where j=4;
+
+select * from mytable;
+select * from table1;
+
+delete from myTable where i> 2;
+
+select * from "APP"."MYTABLE";
+select * from APP.table1;
+
+-- Try some cursors
+get cursor c1 as 'select * from myTable';
+
+next c1;
+next c1;
+
+close c1;
+
+-- Try updatable cursors
+
+autocommit off;
+get cursor c2 as 'select * from myTable for update';
+
+next c2;
+update myTable set i=5 where current of c2;
+close c2;
+
+autocommit on;
+
+select * from table1;
+
+-- Try updatable cursors, with synonym at the top, base table inside.
+autocommit off;
+get cursor c2 as 'select * from app.table1 for update';
+
+next c2;
+update myTable set i=6 where current of c2;
+close c2;
+
+autocommit on;
+
+select * from table1;
+-- TODO: Add more tests here
+
+-- trigger tests
+-- drop and recreate schema test
+-- More negative tests once dependency checking is added
+
+drop view view1;
+drop table table1;

Property changes on: 
java/testing/org/apache/derbyTesting/functionTests/tests/lang/synonym.sql
___________________________________________________________________
Name: svn:eol-style
   + native

Index: java/testing/org/apache/derbyTesting/functionTests/master/synonym.out
===================================================================
--- java/testing/org/apache/derbyTesting/functionTests/master/synonym.out       
(revision 0)
+++ java/testing/org/apache/derbyTesting/functionTests/master/synonym.out       
(revision 0)
@@ -0,0 +1,186 @@
+ij> -- tests for synonym support
+set schema APP;
+0 rows inserted/updated/deleted
+ij> -- negative tests
+-- Create a synonym to itself. Error.
+create synonym syn for syn;
+ERROR 42916: Synonym 'SYN' cannot be created for 'APP.SYN' as it would result 
in a repetitive synonym chain.
+ij> create synonym syn for APP.syn;
+ERROR 42916: Synonym 'SYN' cannot be created for 'APP.SYN' as it would result 
in a repetitive synonym chain.
+ij> create synonym APP.syn for syn;
+ERROR 42916: Synonym 'APP.SYN' cannot be created for 'APP.SYN' as it would 
result in a repetitive synonym chain.
+ij> create synonym APP.syn for APP.syn;
+ERROR 42916: Synonym 'APP.SYN' cannot be created for 'APP.SYN' as it would 
result in a repetitive synonym chain.
+ij> -- Create a simple synonym loop. Error.
+create synonym synonym1 for synonym;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'SYNONYM1' resolved to the object 
'APP.SYNONYM' which is currently undefined.
+ij> create synonym synonym for synonym1;
+ERROR 42916: Synonym 'SYNONYM' cannot be created for 'SYNONYM1' as it would 
result in a repetitive synonym chain.
+ij> drop synonym synonym1;
+0 rows inserted/updated/deleted
+ij> -- Create a larger synonym loop.
+create synonym ts1 for ts;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'TS1' resolved to the object 'APP.TS' 
which is currently undefined.
+ij> create synonym ts2 for ts1;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'TS2' resolved to the object 'APP.TS' 
which is currently undefined.
+ij> create synonym ts3 for ts2;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'TS3' resolved to the object 'APP.TS' 
which is currently undefined.
+ij> create synonym ts4 for ts3;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'TS4' resolved to the object 'APP.TS' 
which is currently undefined.
+ij> create synonym ts5 for ts4;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'TS5' resolved to the object 'APP.TS' 
which is currently undefined.
+ij> create synonym ts6 for ts5;
+0 rows inserted/updated/deleted
+WARNING 01522: The newly defined alias 'TS6' resolved to the object 'APP.TS' 
which is currently undefined.
+ij> create synonym ts for ts6;
+ERROR 42916: Synonym 'TS' cannot be created for 'TS6' as it would result in a 
repetitive synonym chain.
+ij> drop synonym App.ts1;
+0 rows inserted/updated/deleted
+ij> drop synonym "APP".ts2;
+0 rows inserted/updated/deleted
+ij> drop synonym TS3;
+0 rows inserted/updated/deleted
+ij> drop synonym ts4;
+0 rows inserted/updated/deleted
+ij> drop synonym ts5;
+0 rows inserted/updated/deleted
+ij> drop synonym app.ts6;
+0 rows inserted/updated/deleted
+ij> -- Synonyms and table/view share same namespace. Negative tests for this.
+create table table1 (i int, j int);
+0 rows inserted/updated/deleted
+ij> insert into table1 values (1,1), (2,2);
+2 rows inserted/updated/deleted
+ij> create view view1 as select i, j from table1;
+0 rows inserted/updated/deleted
+ij> create synonym table1 for t1;
+ERROR X0Y68: Table/View 'TABLE1' already exists.
+ij> create synonym APP.Table1 for t1;
+ERROR X0Y68: Table/View 'TABLE1' already exists.
+ij> create synonym app.TABLE1 for "APP"."T";
+ERROR X0Y68: Table/View 'TABLE1' already exists.
+ij> create synonym APP.VIEW1 for v1;
+ERROR X0Y68: Table/View 'VIEW1' already exists.
+ij> create synonym "APP"."VIEW1" for app.v;
+ERROR X0Y68: Table/View 'VIEW1' already exists.
+ij> -- Synonyms can't be created on temporary tables
+declare global temporary table session.t1 (c1 int) not logged;
+0 rows inserted/updated/deleted
+ij> create synonym synForTemp for session.t1;
+ERROR XCL51: The requested function can not reference tables in SESSION schema.
+ij> create synonym synForTemp for session."T1";
+ERROR XCL51: The requested function can not reference tables in SESSION schema.
+ij> -- Creating a table or a view when a synonym of that name is present. 
Error.
+create synonym myTable for table1;
+0 rows inserted/updated/deleted
+ij> create table myTable(i int, j int);
+ERROR X0Y68: Synonym 'MYTABLE' already exists.
+ij> create view myTable as select * from table1;
+ERROR X0Y68: Synonym 'MYTABLE' already exists.
+ij> -- Positive test cases
+-- Using synonym in DML
+select * from table1;
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+ij> select * from myTable;
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+ij> insert into myTable values (3,3), (4,4);
+2 rows inserted/updated/deleted
+ij> select * from mytable;
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+3          |3          
+4          |4          
+ij> update myTable set i=3 where j=4;
+1 row inserted/updated/deleted
+ij> select * from mytable;
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+3          |3          
+3          |4          
+ij> select * from table1;
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+3          |3          
+3          |4          
+ij> delete from myTable where i> 2;
+2 rows inserted/updated/deleted
+ij> select * from "APP"."MYTABLE";
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+ij> select * from APP.table1;
+I          |J          
+-----------------------
+1          |1          
+2          |2          
+ij> -- Try some cursors
+get cursor c1 as 'select * from myTable';
+ij> next c1;
+I          |J          
+-----------------------
+1          |1          
+ij> next c1;
+I          |J          
+-----------------------
+2          |2          
+ij> close c1;
+ij> -- Try updatable cursors
+autocommit off;
+ij> get cursor c2 as 'select * from myTable for update';
+ij> next c2;
+I          |J          
+-----------------------
+1          |1          
+ij> update myTable set i=5 where current of c2;
+1 row inserted/updated/deleted
+ij> close c2;
+ij> autocommit on;
+ij> select * from table1;
+I          |J          
+-----------------------
+5          |1          
+2          |2          
+ij> -- Try updatable cursors, with synonym at the top, base table inside.
+autocommit off;
+ij> get cursor c2 as 'select * from app.table1 for update';
+ij> next c2;
+I          |J          
+-----------------------
+5          |1          
+ij> update myTable set i=6 where current of c2;
+1 row inserted/updated/deleted
+ij> close c2;
+ij> autocommit on;
+ij> select * from table1;
+I          |J          
+-----------------------
+6          |1          
+2          |2          
+ij> -- TODO: Add more tests here
+-- trigger tests
+-- drop and recreate schema test
+-- More negative tests once dependency checking is added
+drop view view1;
+0 rows inserted/updated/deleted
+ij> drop table table1;
+0 rows inserted/updated/deleted
+ij> 

Property changes on: 
java/testing/org/apache/derbyTesting/functionTests/master/synonym.out
___________________________________________________________________
Name: svn:eol-style
   + native

Reply via email to