/* * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software;Designed and Developed mainly by many Chinese * opensource volunteers. you can redistribute it and/or modify it under the * terms of the GNU General Public License version 2 only, as published by the * Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Any questions about this component can be directed to it's project Web address * https://code.google.com/p/opencloudb/. * */ package com.akiban.sql.parser; import com.akiban.sql.StandardException; import com.akiban.sql.types.AliasInfo; import com.akiban.sql.types.DataTypeDescriptor; import com.akiban.sql.types.RoutineAliasInfo; import com.akiban.sql.types.SynonymAliasInfo; import com.akiban.sql.types.UDTAliasInfo; import java.util.List; /** * A CreateAliasNode represents a CREATE ALIAS statement. * */ public class CreateAliasNode extends DDLStatementNode { // indexes into routineElements public static final int PARAMETER_ARRAY = 0; public static final int TABLE_NAME = PARAMETER_ARRAY + 1; public static final int DYNAMIC_RESULT_SET_COUNT = TABLE_NAME + 1; public static final int LANGUAGE = DYNAMIC_RESULT_SET_COUNT + 1; public static final int EXTERNAL_NAME = LANGUAGE + 1; public static final int PARAMETER_STYLE = EXTERNAL_NAME + 1; public static final int SQL_CONTROL = PARAMETER_STYLE + 1; public static final int DETERMINISTIC = SQL_CONTROL + 1; public static final int NULL_ON_NULL_INPUT = DETERMINISTIC + 1; public static final int RETURN_TYPE = NULL_ON_NULL_INPUT + 1; public static final int ROUTINE_SECURITY_DEFINER = RETURN_TYPE + 1; public static final int INLINE_DEFINITION = ROUTINE_SECURITY_DEFINER + 1; // Keep ROUTINE_ELEMENT_COUNT last (determines set cardinality). // Note: Remember to also update the map ROUTINE_CLAUSE_NAMES in // SQLGrammar.jj when elements are added. public static final int ROUTINE_ELEMENT_COUNT = INLINE_DEFINITION + 1; private String javaClassName; private String methodName; private boolean createOrReplace; private AliasInfo.Type aliasType; private AliasInfo aliasInfo; private String definition; /** * Initializer for a CreateAliasNode * * @param aliasName The name of the alias * @param targetObject Target name * @param methodName The method name * @param aliasType The alias type * * @exception StandardException Thrown on error */ public void init(Object aliasName, Object targetObject, Object methodName, Object aliasSpecificInfo, Object aliasType, Object createOrReplace) throws StandardException { TableName qn = (TableName)aliasName; this.aliasType = (AliasInfo.Type)aliasType; this.createOrReplace = (Boolean)createOrReplace; initAndCheck(qn); switch (this.aliasType) { case UDT: this.javaClassName = (String)targetObject; aliasInfo = new UDTAliasInfo(); implicitCreateSchema = true; break; case PROCEDURE: case FUNCTION: { //routineElements contains the description of the procedure. // // 0 - Object[] 3 element array for parameters // 1 - TableName - specific name // 2 - Integer - dynamic result set count // 3 - String language // 4 - String external name (also passed directly to create alias node - ignore // 5 - ParameterStyle parameter style // 6 - SQLAllowed - SQL control // 7 - Boolean - CALLED ON NULL INPUT (always TRUE for procedures) // 8 - DataTypeDescriptor - return type (always NULL for procedures) // 9 - Boolean - definers rights // 10 - String - inline definition Object[] routineElements = (Object[])aliasSpecificInfo; Object[] parameters = (Object[])routineElements[PARAMETER_ARRAY]; int paramCount = ((List)parameters[0]).size(); String[] names = null; DataTypeDescriptor[] types = null; int[] modes = null; if (paramCount != 0) { names = new String[paramCount]; ((List<String>)parameters[0]).toArray(names); types = new DataTypeDescriptor[paramCount]; ((List<DataTypeDescriptor>)parameters[1]).toArray(types); modes = new int[paramCount]; for (int i = 0; i < paramCount; i++) { int currentMode = ((List<Integer>)parameters[2]).get(i).intValue(); modes[i] = currentMode; } if (paramCount > 1) { String[] dupNameCheck = new String[paramCount]; System.arraycopy(names, 0, dupNameCheck, 0, paramCount); java.util.Arrays.sort(dupNameCheck); for (int dnc = 1; dnc < dupNameCheck.length; dnc++) { if (! dupNameCheck[dnc].equals("") && dupNameCheck[dnc].equals(dupNameCheck[dnc - 1])) throw new StandardException("Duplicate parameter name"); } } } Integer drso = (Integer)routineElements[DYNAMIC_RESULT_SET_COUNT]; int drs = drso == null ? 0 : drso.intValue(); RoutineAliasInfo.SQLAllowed sqlAllowed = (RoutineAliasInfo.SQLAllowed)routineElements[SQL_CONTROL]; Boolean isDeterministicO = (Boolean)routineElements[DETERMINISTIC]; boolean isDeterministic = (isDeterministicO == null) ? false : isDeterministicO.booleanValue(); Boolean definersRightsO = (Boolean)routineElements[ROUTINE_SECURITY_DEFINER]; boolean definersRights = (definersRightsO == null) ? false : definersRightsO.booleanValue(); Boolean calledOnNullInputO = (Boolean)routineElements[NULL_ON_NULL_INPUT]; boolean calledOnNullInput = (calledOnNullInputO == null) ? false : calledOnNullInputO.booleanValue(); DataTypeDescriptor returnType = (DataTypeDescriptor)routineElements[RETURN_TYPE]; String language = (String)routineElements[LANGUAGE]; String pstyle = (String)routineElements[PARAMETER_STYLE]; this.definition = (String)routineElements[INLINE_DEFINITION]; this.javaClassName = (String)targetObject; this.methodName = (String)methodName; aliasInfo = new RoutineAliasInfo(this.methodName, paramCount, names, types, modes, drs, language, pstyle, sqlAllowed, isDeterministic, definersRights, calledOnNullInput, returnType); implicitCreateSchema = true; } break; case SYNONYM: String targetSchema = null; implicitCreateSchema = true; TableName t = (TableName)targetObject; if (t.getSchemaName() != null) targetSchema = t.getSchemaName(); aliasInfo = new SynonymAliasInfo(targetSchema, t.getTableName()); break; default: assert false : "Unexpected value for aliasType " + aliasType; } } public String getJavaClassName() { return javaClassName; } public String getMethodName() { return methodName; } public String getExternalName() { if (javaClassName == null) return methodName; else if (methodName == null) return javaClassName; else return javaClassName + "." + methodName; } public boolean isCreateOrReplace() { return createOrReplace; } public AliasInfo.Type getAliasType() { return aliasType; } public AliasInfo getAliasInfo() { return aliasInfo; } public String getDefinition() { return definition; } /** * Convert this object to a String. See comments in QueryTreeNode.java * for how this should be done for tree printing. * * @return This object as a String */ public String toString() { return "aliasType: " + aliasType + "\n" + "aliasInfo: " + aliasInfo + "\n" + "createOrReplace: " + createOrReplace + "\n" + ((definition != null) ? ("definition: " + definition + "\n") : ("javaClassName: " + javaClassName + "\n" + "methodName: " + methodName + "\n")) + super.toString(); } /** * Fill this node with a deep copy of the given node. */ public void copyFrom(QueryTreeNode node) throws StandardException { super.copyFrom(node); CreateAliasNode other = (CreateAliasNode)node; this.javaClassName = other.javaClassName; this.methodName = other.methodName; this.definition = other.definition; this.aliasType = other.aliasType; this.aliasInfo = other.aliasInfo; // TODO: Clone? } public String statementToString() { switch (this.aliasType) { case UDT: return "CREATE TYPE"; case PROCEDURE: return "CREATE PROCEDURE"; case SYNONYM: return "CREATE SYNONYM"; default: return "CREATE FUNCTION"; } } }