public Query handleInsertStatement(ZInsert s, TransactionId tId)
      throws DbException, simpledb.ParsingException
      {
    int tableId;
    try {
      tableId = Database.getCatalog().getTableId(s.getTable()); // will
                                                                // fall
      // through if
      // table
      // doesn't
      // exist
    } catch (NoSuchElementException e) {
      throw new simpledb.ParsingException("Unknown table : " + s.getTable());
    }

    TupleDesc td = Database.getCatalog().getTupleDesc(tableId);

    Tuple t = new Tuple(td);
    int i = 0;
    DbIterator newTups;

    if (s.getValues() != null) {
      @SuppressWarnings("unchecked")
      Vector<ZExp> values = s.getValues();
      if (td.numFields() != values.size()) {
        throw new simpledb.ParsingException(
            "INSERT statement does not contain same number of fields as table " + s.getTable());
      }
      for (ZExp e : values) {

        if (!(e instanceof ZConstant))
          throw new simpledb.ParsingException(
              "Complex expressions not allowed in INSERT statements.");
        ZConstant zc = (ZConstant) e;
        if (zc.getType() == ZConstant.NUMBER) {
          if (td.getFieldType(i) != Type.INT_TYPE) {
            throw new simpledb.ParsingException("Value " + zc.getValue()
                + " is not an integer, expected a string.");
          }
          IntField f = new IntField(new Integer(zc.getValue()).intValue());
          t.setField(i, f);
        } else if (zc.getType() == ZConstant.STRING) {
          if (td.getFieldType(i) != Type.STRING_TYPE) {
            throw new simpledb.ParsingException("Value " + zc.getValue()
                + " is a string, expected an integer.");
          }
          StringField f = new StringField(zc.getValue(), Type.STRING_LEN);
          t.setField(i, f);
        } else {
          throw new simpledb.ParsingException("Only string or int fields are supported.");
        }

        i++;
      }
      ArrayList<Tuple> tups = new ArrayList<Tuple>();
      tups.add(t);
      newTups = new TupleArrayIterator(tups);

    } else {
      ZQuery zq = s.getQuery();
      LogicalPlan lp = parseQueryLogicalPlan(tId, zq);
      newTups = lp.physicalPlan(tId, TableStats.getStatsMap(), explain);
    }
    Query insertQ = new Query(tId);
    insertQ.setPhysicalPlan(new Insert(tId, newTups, tableId));
    return insertQ;
  }