1 /* Copyright (c) 2001-2015, The HSQL Development Group 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of the HSQL Development Group nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 32 package org.hsqldb; 33 34 import org.hsqldb.error.Error; 35 import org.hsqldb.error.ErrorCode; 36 import org.hsqldb.lib.OrderedHashSet; 37 import org.hsqldb.lib.OrderedIntHashSet; 38 import org.hsqldb.result.Result; 39 40 /** 41 * Implementation of Statement for condition handler objects.<p> 42 * 43 * @author Fred Toussi (fredt@users dot sourceforge.net) 44 * @version 2.3.3 45 * @since 1.9.0 46 */ 47 public class StatementHandler extends Statement { 48 49 public static final int NONE = 0; 50 public static final int SQL_EXCEPTION = 1; 51 public static final int SQL_WARNING = 2; 52 public static final int SQL_NOT_FOUND = 3; 53 public static final int SQL_STATE = 4; 54 55 // 56 public static final int CONTINUE = 5; 57 public static final int EXIT = 6; 58 public static final int UNDO = 7; 59 60 // 61 public final int handlerType; 62 63 // 64 private OrderedIntHashSet conditionGroups = new OrderedIntHashSet(); 65 private OrderedHashSet conditionStates = new OrderedHashSet(); 66 private Statement statement; 67 68 // 69 public static final StatementHandler[] emptyExceptionHandlerArray = 70 new StatementHandler[]{}; 71 StatementHandler(int handlerType)72 StatementHandler(int handlerType) { 73 74 super(StatementTypes.HANDLER, StatementTypes.X_SQL_CONTROL); 75 76 this.handlerType = handlerType; 77 } 78 addConditionState(String sqlState)79 public void addConditionState(String sqlState) { 80 81 boolean result = conditionStates.add(sqlState); 82 83 result &= conditionGroups.isEmpty(); 84 85 if (!result) { 86 throw Error.error(ErrorCode.X_42612); 87 } 88 } 89 addConditionType(int conditionType)90 public void addConditionType(int conditionType) { 91 92 boolean result = conditionGroups.add(conditionType); 93 94 result &= conditionStates.isEmpty(); 95 96 if (!result) { 97 throw Error.error(ErrorCode.X_42612); 98 } 99 } 100 addStatement(Statement s)101 public void addStatement(Statement s) { 102 statement = s; 103 } 104 handlesConditionType(int type)105 public boolean handlesConditionType(int type) { 106 return conditionGroups.contains(type); 107 } 108 handlesCondition(String sqlState)109 public boolean handlesCondition(String sqlState) { 110 111 if (conditionStates.contains(sqlState)) { 112 return true; 113 } 114 115 String conditionClass = sqlState.substring(0, 2); 116 117 if (conditionStates.contains(conditionClass)) { 118 return true; 119 } 120 121 if (conditionClass.equals("01")) { 122 return conditionGroups.contains(SQL_WARNING); 123 } 124 125 if (conditionClass.equals("02")) { 126 return conditionGroups.contains(SQL_NOT_FOUND); 127 } 128 129 return conditionGroups.contains(SQL_EXCEPTION); 130 } 131 getConditionTypes()132 public int[] getConditionTypes() { 133 return conditionGroups.toArray(); 134 } 135 getConditionStates()136 public String[] getConditionStates() { 137 138 String[] array = new String[conditionStates.size()]; 139 140 conditionStates.toArray(array); 141 142 return array; 143 } 144 resolve(Session session)145 public void resolve(Session session) { 146 147 if (statement != null) { 148 statement.resolve(session); 149 150 readTableNames = statement.getTableNamesForRead(); 151 writeTableNames = statement.getTableNamesForWrite(); 152 } 153 } 154 execute(Session session)155 public Result execute(Session session) { 156 157 if (statement != null) { 158 return statement.execute(session); 159 } else { 160 return Result.updateZeroResult; 161 } 162 } 163 describe(Session session)164 public String describe(Session session) { 165 return ""; 166 } 167 getReferences()168 public OrderedHashSet getReferences() { 169 170 if (statement == null) { 171 return new OrderedHashSet(); 172 } 173 174 return statement.getReferences(); 175 } 176 getSQL()177 public String getSQL() { 178 179 StringBuffer sb = new StringBuffer(64); 180 String s; 181 182 s = handlerType == CONTINUE ? Tokens.T_CONTINUE 183 : handlerType == EXIT ? Tokens.T_EXIT 184 : Tokens.T_UNDO; 185 186 sb.append(Tokens.T_DECLARE).append(' ').append(s).append(' '); 187 sb.append(Tokens.T_HANDLER).append(' ').append(Tokens.T_FOR); 188 sb.append(' '); 189 190 for (int i = 0; i < conditionStates.size(); i++) { 191 if (i > 0) { 192 sb.append(','); 193 } 194 195 sb.append(Tokens.T_SQLSTATE).append(' '); 196 sb.append('\'').append(conditionStates.get(i)).append('\''); 197 } 198 199 for (int i = 0; i < conditionGroups.size(); i++) { 200 if (i > 0) { 201 sb.append(','); 202 } 203 204 switch (conditionGroups.get(i)) { 205 206 case SQL_EXCEPTION : 207 sb.append(Tokens.T_SQLEXCEPTION); 208 break; 209 210 case SQL_WARNING : 211 sb.append(Tokens.T_SQLWARNING); 212 break; 213 214 case SQL_NOT_FOUND : 215 sb.append(Tokens.T_NOT).append(' ').append(Tokens.FOUND); 216 break; 217 } 218 } 219 220 if (statement != null) { 221 sb.append(' ').append(statement.getSQL()); 222 } 223 224 return sb.toString(); 225 } 226 isCatalogLock()227 public boolean isCatalogLock() { 228 return false; 229 } 230 isCatalogChange()231 public boolean isCatalogChange() { 232 return false; 233 } 234 } 235