// int : headersize (0 if no more tables), String : tablename, int : operation,
  // String : schemaname
  protected String readTableInit() throws IOException, HsqlException {

    boolean more = readRow(rowIn, 0);

    if (!more) {
      return null;
    }

    String s = rowIn.readString();

    // operation is always INSERT
    int checkOp = rowIn.readIntData();

    if (checkOp == ScriptWriterBase.INSERT_WITH_SCHEMA) {
      currentSchema = rowIn.readString();
    } else {
      currentSchema = null;
    }

    if (checkOp != ScriptWriterBase.INSERT && checkOp != ScriptWriterBase.INSERT_WITH_SCHEMA) {
      throw Trace.error(Trace.ERROR_IN_SCRIPT_FILE, Trace.ERROR_IN_BINARY_SCRIPT_2);
    }

    return s;
  }
  Type readDataType(RowInputBinary in) throws IOException {

    int typeCode = in.readType();
    long size = in.readLong();
    int scale = in.readInt();

    return Type.getType(typeCode, 0, size, scale);
  }
  // int : row size (0 if no more rows) ,
  // BinaryServerRowInput : row (column values)
  protected boolean readRow(Table t) throws IOException, HsqlException {

    boolean more = readRow(rowIn, 0);

    if (!more) {
      return false;
    }

    Object[] data = rowIn.readData(t.getColumnTypes());

    t.insertFromScript(data);

    return true;
  }
  /** Initializes this connection and runs the request handling loop until closed. */
  public void run() {

    init();

    if (session != null) {
      try {
        while (keepAlive) {
          Result resultIn = Result.read(rowIn, dataInput);

          server.printRequest(mThread, resultIn);

          Result resultOut;

          if (resultIn.mode == ResultConstants.HSQLRESETSESSION) {
            resultOut = resetSession();
          } else {
            resultOut = session.execute(resultIn);
          }

          Result.write(resultOut, rowOut, dataOutput);
          rowOut.setBuffer(mainBuffer);
          rowIn.resetRow(mainBuffer.length);
        }
      } catch (IOException e) {

        // fredt - is thrown when connection drops
        server.printWithThread(mThread + ":disconnected " + user);
      } catch (HsqlException e) {

        // fredt - is thrown while constructing the result
        server.printStackTrace(e);
      }
    }

    close();
  }
  private static Result newResult(Session session, DataInput dataInput, RowInputBinary in, int mode)
      throws IOException, HsqlException {

    Result result = newResult(mode);
    int length = dataInput.readInt();

    in.resetRow(0, length);

    byte[] byteArray = in.getBuffer();
    final int offset = 4;

    dataInput.readFully(byteArray, offset, length - offset);

    switch (mode) {
      case ResultConstants.GETSESSIONATTR:
        result.statementReturnType = in.readByte();
        break;

      case ResultConstants.DISCONNECT:
      case ResultConstants.RESETSESSION:
      case ResultConstants.STARTTRAN:
        break;

      case ResultConstants.PREPARE:
        result.setStatementType(in.readByte());

        result.mainString = in.readString();
        result.rsProperties = in.readByte();
        result.generateKeys = in.readByte();

        if (result.generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES
            || result.generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES) {
          result.generatedMetaData = new ResultMetaData(in);
        }
        break;

      case ResultConstants.CLOSE_RESULT:
        result.id = in.readLong();
        break;

      case ResultConstants.FREESTMT:
        result.statementID = in.readLong();
        break;

      case ResultConstants.EXECDIRECT:
        result.updateCount = in.readInt();
        result.fetchSize = in.readInt();
        result.statementReturnType = in.readByte();
        result.mainString = in.readString();
        result.rsProperties = in.readByte();
        result.queryTimeout = in.readShort();
        result.generateKeys = in.readByte();

        if (result.generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES
            || result.generateKeys == ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES) {
          result.generatedMetaData = new ResultMetaData(in);
        }
        break;

      case ResultConstants.CONNECT:
        result.databaseName = in.readString();
        result.mainString = in.readString();
        result.subString = in.readString();
        result.zoneString = in.readString();
        result.updateCount = in.readInt();
        break;

      case ResultConstants.ERROR:
      case ResultConstants.WARNING:
        result.mainString = in.readString();
        result.subString = in.readString();
        result.errorCode = in.readInt();
        break;

      case ResultConstants.CONNECTACKNOWLEDGE:
        result.databaseID = in.readInt();
        result.sessionID = in.readLong();
        result.databaseName = in.readString();
        result.mainString = in.readString();
        break;

      case ResultConstants.UPDATECOUNT:
        result.updateCount = in.readInt();
        break;

      case ResultConstants.ENDTRAN:
        {
          int type = in.readInt();

          result.setActionType(type); // endtran type

          switch (type) {
            case ResultConstants.TX_SAVEPOINT_NAME_RELEASE:
            case ResultConstants.TX_SAVEPOINT_NAME_ROLLBACK:
              result.mainString = in.readString(); // savepoint name
              break;

            case ResultConstants.TX_COMMIT:
            case ResultConstants.TX_ROLLBACK:
            case ResultConstants.TX_COMMIT_AND_CHAIN:
            case ResultConstants.TX_ROLLBACK_AND_CHAIN:
            case ResultConstants.PREPARECOMMIT:
              break;

            default:
              throw Error.runtimeError(ErrorCode.U_S0500, "Result");
          }

          break;
        }
      case ResultConstants.SETCONNECTATTR:
        {
          int type = in.readInt(); // attr type

          result.setConnectionAttrType(type);

          switch (type) {
            case ResultConstants.SQL_ATTR_SAVEPOINT_NAME:
              result.mainString = in.readString(); // savepoint name
              break;

              //  case ResultConstants.SQL_ATTR_AUTO_IPD :
              //      - always true
              //  default: throw - case never happens
            default:
              throw Error.runtimeError(ErrorCode.U_S0500, "Result");
          }

          break;
        }
      case ResultConstants.PREPARE_ACK:
        result.statementReturnType = in.readByte();
        result.statementID = in.readLong();
        result.rsProperties = in.readByte();
        result.metaData = new ResultMetaData(in);
        result.parameterMetaData = new ResultMetaData(in);
        break;

      case ResultConstants.CALL_RESPONSE:
        result.updateCount = in.readInt();
        result.fetchSize = in.readInt();
        result.statementID = in.readLong();
        result.statementReturnType = in.readByte();
        result.rsProperties = in.readByte();
        result.metaData = new ResultMetaData(in);
        result.valueData = readSimple(in, result.metaData);
        break;

      case ResultConstants.EXECUTE:
        result.updateCount = in.readInt();
        result.fetchSize = in.readInt();
        result.statementID = in.readLong();
        result.rsProperties = in.readByte();
        result.queryTimeout = in.readShort();

        Statement statement = session.statementManager.getStatement(session, result.statementID);

        if (statement == null) {

          // invalid statement
          result.mode = ResultConstants.EXECUTE_INVALID;
          result.valueData = ValuePool.emptyObjectArray;

          break;
        }

        result.statement = statement;
        result.metaData = result.statement.getParametersMetaData();
        result.valueData = readSimple(in, result.metaData);
        break;

      case ResultConstants.UPDATE_RESULT:
        {
          result.id = in.readLong();

          int type = in.readInt();

          result.setActionType(type);

          result.metaData = new ResultMetaData(in);
          result.valueData = readSimple(in, result.metaData);

          break;
        }
      case ResultConstants.BATCHEXECRESPONSE:
      case ResultConstants.BATCHEXECUTE:
      case ResultConstants.BATCHEXECDIRECT:
      case ResultConstants.SETSESSIONATTR:
        {
          result.updateCount = in.readInt();
          result.fetchSize = in.readInt();
          result.statementID = in.readLong();
          result.queryTimeout = in.readShort();
          result.metaData = new ResultMetaData(in);

          result.navigator.readSimple(in, result.metaData);

          break;
        }
      case ResultConstants.PARAM_METADATA:
        {
          result.metaData = new ResultMetaData(in);

          result.navigator.read(in, result.metaData);

          break;
        }
      case ResultConstants.REQUESTDATA:
        {
          result.id = in.readLong();
          result.updateCount = in.readInt();
          result.fetchSize = in.readInt();

          break;
        }
      case ResultConstants.DATAHEAD:
      case ResultConstants.DATA:
      case ResultConstants.GENERATED:
        {
          result.id = in.readLong();
          result.updateCount = in.readInt();
          result.fetchSize = in.readInt();
          result.rsProperties = in.readByte();
          result.metaData = new ResultMetaData(in);
          result.navigator = new RowSetNavigatorClient();

          result.navigator.read(in, result.metaData);

          break;
        }
      case ResultConstants.DATAROWS:
        {
          result.metaData = new ResultMetaData(in);
          result.navigator = new RowSetNavigatorClient();

          result.navigator.read(in, result.metaData);

          break;
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "Result");
    }

    return result;
  }
  private static Object[] readSimple(RowInputBinary in, ResultMetaData meta) throws IOException {

    int size = in.readInt();

    return in.readData(meta.columnTypes);
  }
  ResultMetaData(RowInputBinary in) throws IOException {

    type = in.readInt();
    columnCount = in.readInt();

    switch (type) {
      case UPDATE_RESULT_METADATA:
      case SIMPLE_RESULT_METADATA:
        {
          columnTypes = new Type[columnCount];

          for (int i = 0; i < columnCount; i++) {
            int type = in.readType();

            columnTypes[i] = Type.getDefaultType(type);
          }

          return;
        }
      case GENERATED_INDEX_METADATA:
        {
          colIndexes = new int[columnCount];

          for (int i = 0; i < columnCount; i++) {
            colIndexes[i] = in.readInt();
          }

          return;
        }
      case GENERATED_NAME_METADATA:
        {
          columnLabels = new String[columnCount];

          for (int i = 0; i < columnCount; i++) {
            columnLabels[i] = in.readString();
          }

          return;
        }
      case PARAM_METADATA:
        {
          columnTypes = new Type[columnCount];
          columnLabels = new String[columnCount];
          paramModes = new byte[columnCount];
          paramNullable = new byte[columnCount];

          for (int i = 0; i < columnCount; i++) {
            columnTypes[i] = readDataType(in);
            columnLabels[i] = in.readString();

            decodeParamColumnAttrs(in.readByte(), i);
          }

          return;
        }
      case RESULT_METADATA:
        {
          extendedColumnCount = in.readInt();
          columnTypes = new Type[extendedColumnCount];
          columnLabels = new String[columnCount];
          columns = new ColumnBase[columnCount];

          if (columnCount != extendedColumnCount) {
            colIndexes = new int[columnCount];
          }

          for (int i = 0; i < extendedColumnCount; i++) {
            Type type = readDataType(in);

            columnTypes[i] = type;
          }

          for (int i = 0; i < columnCount; i++) {
            columnLabels[i] = in.readString();

            String catalog = in.readString();
            String schema = in.readString();
            String table = in.readString();
            String name = in.readString();
            ColumnBase column = new ColumnBase(catalog, schema, table, name);

            column.setType(columnTypes[i]);
            decodeTableColumnAttrs(in.readByte(), column);

            columns[i] = column;
          }

          if (columnCount != extendedColumnCount) {
            for (int i = 0; i < columnCount; i++) {
              colIndexes[i] = in.readInt();
            }
          }

          return;
        }
      default:
        {
          throw Error.runtimeError(ErrorCode.U_S0500, "ResultMetaData");
        }
    }
  }