Java Code Examples for com.google.rpc.Code#INVALID_ARGUMENT

The following examples show how to use com.google.rpc.Code#INVALID_ARGUMENT . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DeleteWorker.java    From spanner-jdbc with MIT License 6 votes vote down vote up
private static Select createSelect(CloudSpannerConnection connection, Delete delete)
    throws SQLException {
  TableKeyMetaData table =
      connection.getTable(CloudSpannerDriver.unquoteIdentifier(delete.getTable().getName()));
  List<String> keyCols = table.getKeyColumns().stream()
      .map(x -> CloudSpannerDriver.quoteIdentifier(delete.getTable().getName()) + "."
          + CloudSpannerDriver.quoteIdentifier(x))
      .collect(Collectors.toList());
  StringBuilder sql = new StringBuilder();
  sql.append("SELECT ").append(String.join(", ", keyCols));
  sql.append("\nFROM ").append(CloudSpannerDriver.quoteIdentifier(delete.getTable().getName()));
  sql.append("\nWHERE ").append(delete.getWhere().toString());

  try {
    return (Select) CCJSqlParserUtil.parse(sql.toString());
  } catch (JSQLParserException e) {
    throw new CloudSpannerSQLException("Could not parse generated SELECT statement: " + sql,
        Code.INVALID_ARGUMENT);
  }
}
 
Example 2
Source File: DDLStatement.java    From spanner-jdbc with MIT License 6 votes vote down vote up
private static List<String> getTokens(String sql, int maxTokens) throws SQLException {
  List<String> res = new ArrayList<>(maxTokens);
  int tokenNumber = 0;
  StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(sql));
  tokenizer.eolIsSignificant(false);
  tokenizer.wordChars('_', '_');
  tokenizer.wordChars('"', '"');
  tokenizer.wordChars('\'', '\'');
  tokenizer.quoteChar('`');
  try {
    while (tokenizer.nextToken() != StreamTokenizer.TT_EOF
        && (tokenizer.ttype == StreamTokenizer.TT_WORD || tokenizer.ttype == '`')
        && tokenNumber < maxTokens) {
      res.add(tokenizer.sval);
      tokenNumber++;
    }
  } catch (IOException e) {
    throw new CloudSpannerSQLException(
        "Could not parse DDL statement '" + sql + "'. Error: " + e.getMessage(),
        Code.INVALID_ARGUMENT, e);
  }
  return res;
}
 
Example 3
Source File: CloudSpannerPreparedStatement.java    From spanner-jdbc with MIT License 6 votes vote down vote up
@Override
public CloudSpannerParameterMetaData getParameterMetaData() throws SQLException {
  // parse the SQL statement without executing it
  try {
    if (isDDLStatement()) {
      throw new CloudSpannerSQLException("Cannot get parameter meta data for DDL statement",
          Code.INVALID_ARGUMENT);
    }
    Statement statement = CCJSqlParserUtil.parse(sanitizeSQL(sql));
    if (statement instanceof Insert || statement instanceof Update
        || statement instanceof Delete) {
      // Create mutation, but don't do anything with it. This
      // initializes column names of the parameter store.
      createMutations(sql, false, true);
    } else if (statement instanceof Select) {
      // Create select builder, but don't do anything with it. This
      // initializes column names of the parameter store.
      createSelectBuilder(statement, sql);
    }
  } catch (JSQLParserException | TokenMgrException e) {
    throw new CloudSpannerSQLException(PARSE_ERROR + sql + ": " + e.getLocalizedMessage(),
        Code.INVALID_ARGUMENT, e);
  }
  return new CloudSpannerParameterMetaData(this);
}
 
Example 4
Source File: CloudSpannerPreparedStatement.java    From spanner-jdbc with MIT License 6 votes vote down vote up
@Override
public ResultSet executeQuery() throws SQLException {
  CustomDriverStatement custom = getCustomDriverStatement(sqlTokens);
  if (custom != null && custom.isQuery()) {
    return custom.executeQuery(sqlTokens);
  }
  Statement statement;
  try {
    statement = CCJSqlParserUtil.parse(sanitizeSQL(sql));
  } catch (JSQLParserException | TokenMgrException e) {
    throw new CloudSpannerSQLException(PARSE_ERROR + sql + ": " + e.getLocalizedMessage(),
        Code.INVALID_ARGUMENT, e);
  }
  if (statement instanceof Select) {
    determineForceSingleUseReadContext((Select) statement);
    com.google.cloud.spanner.Statement.Builder builder = createSelectBuilder(statement, sql);
    try (ReadContext context = getReadContext()) {
      com.google.cloud.spanner.ResultSet rs = context.executeQuery(builder.build());
      return new CloudSpannerResultSet(this, rs, sql);
    }
  }
  throw new CloudSpannerSQLException(
      "SQL statement not suitable for executeQuery. Expected SELECT-statement.",
      Code.INVALID_ARGUMENT);
}
 
Example 5
Source File: CloudSpannerPreparedStatement.java    From spanner-jdbc with MIT License 6 votes vote down vote up
private InsertWorker createInsertWithSelectStatement(Insert insert, boolean forceUpdate)
    throws SQLException {
  Select select = insert.getSelect();
  if (select == null) {
    throw new CloudSpannerSQLException("Insert statement must contain a select statement",
        Code.INVALID_ARGUMENT);
  }
  boolean isDuplicate = insert.isUseDuplicate();
  InsertWorker.DMLOperation mode;
  if (forceUpdate)
    mode = DMLOperation.UPDATE;
  else if (isDuplicate)
    mode = DMLOperation.ONDUPLICATEKEYUPDATE;
  else
    mode = DMLOperation.INSERT;
  return new InsertWorker(getConnection(), select, insert, getParameterStore(),
      getConnection().isAllowExtendedMode(), mode);
}
 
Example 6
Source File: DDLStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
boolean shouldExecute(CloudSpannerConnection connection) throws SQLException {
  if (getExistsStatement() == null || getExistsStatement() == ExistsStatement.NONE)
    return true;
  if (getExistsStatement() == ExistsStatement.IF_NOT_EXISTS && getCommand() == Command.DROP)
    throw new CloudSpannerSQLException(
        "Invalid argument: Cannot use 'IF NOT EXISTS' when dropping an object",
        Code.INVALID_ARGUMENT);
  if (getExistsStatement() == ExistsStatement.IF_EXISTS && getCommand() == Command.CREATE)
    throw new CloudSpannerSQLException(
        "Invalid argument: Cannot use 'IF EXISTS' when creating an object",
        Code.INVALID_ARGUMENT);

  return getExistsStatement().shouldExecute(getObjectType().exists(connection, getObjectName()));
}
 
Example 7
Source File: CloudSpannerArray.java    From spanner-jdbc with MIT License 5 votes vote down vote up
static CloudSpannerArray createArray(String typeName, Object[] elements) throws SQLException {
  for (CloudSpannerDataType type : CloudSpannerDataType.values()) {
    if (type.getTypeName().equalsIgnoreCase(typeName)) {
      return new CloudSpannerArray(type, elements);
    }
  }
  throw new CloudSpannerSQLException("Data type " + typeName + " is unknown",
      Code.INVALID_ARGUMENT);
}
 
Example 8
Source File: CloudSpannerXAConnection.java    From spanner-jdbc with MIT License 5 votes vote down vote up
/**
 * Preconditions: 1. Flags is one of TMSUCCESS, TMFAIL, TMSUSPEND 2. xid != null 3. Connection is
 * associated with transaction xid
 *
 * Implementation deficiency preconditions: 1. Flags is not TMSUSPEND
 *
 * Postconditions: 1. connection is disassociated from the transaction.
 * 
 * @see XAResource#end(Xid, int)
 */
@Override
public void end(Xid xid, int flags) throws XAException {
  if (logger.logDebug()) {
    debug("ending transaction xid = " + xid);
  }

  // Check preconditions

  if (flags != XAResource.TMSUSPEND && flags != XAResource.TMFAIL
      && flags != XAResource.TMSUCCESS) {
    throw new CloudSpannerXAException(CloudSpannerXAException.INVALID_FLAGS,
        Code.INVALID_ARGUMENT, XAException.XAER_INVAL);
  }

  if (xid == null) {
    throw new CloudSpannerXAException(CloudSpannerXAException.XID_NOT_NULL, Code.INVALID_ARGUMENT,
        XAException.XAER_INVAL);
  }

  if (state != STATE_ACTIVE || !currentXid.equals(xid)) {
    throw new CloudSpannerXAException(CloudSpannerXAException.END_WITHOUT_START,
        Code.FAILED_PRECONDITION, XAException.XAER_PROTO);
  }

  // Check implementation deficiency preconditions
  if (flags == XAResource.TMSUSPEND) {
    throw new CloudSpannerXAException(CloudSpannerXAException.SUSPEND_NOT_IMPLEMENTED,
        Code.UNIMPLEMENTED, XAException.XAER_RMERR);
  }

  // We ignore TMFAIL. It's just a hint to the RM. We could roll back
  // immediately
  // if TMFAIL was given.

  // All clear. We don't have any real work to do.
  state = STATE_ENDED;
}
 
Example 9
Source File: CloudSpannerPreparedStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
private DeleteWorker createDeleteWorker(Delete delete) throws SQLException {
  if (delete.getTable() == null
      || (delete.getTables() != null && !delete.getTables().isEmpty())) {
    throw new CloudSpannerSQLException("DELETE statement must contain only one table",
        Code.INVALID_ARGUMENT);
  }
  return new DeleteWorker(getConnection(), delete, getParameterStore(),
      getConnection().isAllowExtendedMode());
}
 
Example 10
Source File: CloudSpannerStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public ResultSet executeQuery(String[] sqlTokens) throws SQLException {
  if (sqlTokens.length == 1)
    return getConnection().getDynamicConnectionProperties(CloudSpannerStatement.this);
  if (sqlTokens.length == 2)
    return getConnection().getDynamicConnectionProperty(CloudSpannerStatement.this,
        sqlTokens[1]);
  throw new CloudSpannerSQLException(
      "Invalid argument(s) for GET_CONNECTION_PROPERTY. Expected \"GET_CONNECTION_PROPERTY propertyName\" or \"GET_CONNECTION_PROPERTY\"",
      Code.INVALID_ARGUMENT);
}
 
Example 11
Source File: CloudSpannerConnection.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public void setTransactionIsolation(int level) throws SQLException {
  checkClosed();
  if (level != Connection.TRANSACTION_SERIALIZABLE) {
    throw new CloudSpannerSQLException(
        "Transaction level " + level
            + " is not supported. Only Connection.TRANSACTION_SERIALIZABLE is supported",
        Code.INVALID_ARGUMENT);
  }
}
 
Example 12
Source File: CloudSpannerStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public ResultSet executeQuery(String[] sqlTokens) throws SQLException {
  if (sqlTokens.length != 1)
    throw new CloudSpannerSQLException(
        "Invalid argument(s) for SHOW_DDL_OPERATIONS. Expected \"SHOW_DDL_OPERATIONS\"",
        Code.INVALID_ARGUMENT);
  return getConnection().getRunningDDLOperations(CloudSpannerStatement.this);
}
 
Example 13
Source File: CloudSpannerStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public int executeUpdate(String[] sqlTokens) throws SQLException {
  if (sqlTokens.length != 1)
    throw new CloudSpannerSQLException(
        "Invalid argument(s) for CLEAN_DDL_OPERATIONS. Expected \"CLEAN_DDL_OPERATIONS\"",
        Code.INVALID_ARGUMENT);
  return getConnection().clearFinishedDDLOperations();
}
 
Example 14
Source File: CloudSpannerStatement.java    From spanner-jdbc with MIT License 5 votes vote down vote up
@Override
public int executeUpdate(String[] sqlTokens) throws SQLException {
  if (sqlTokens.length != 1)
    throw new CloudSpannerSQLException(
        "Invalid argument(s) for WAIT_FOR_DDL_OPERATIONS. Expected \"WAIT_FOR_DDL_OPERATIONS\"",
        Code.INVALID_ARGUMENT);
  getConnection().waitForDdlOperations();
  return 0;
}
 
Example 15
Source File: DeleteKeyBuilder.java    From spanner-jdbc with MIT License 5 votes vote down vote up
public Key.Builder getKeyBuilder() throws SQLException {
  Key.Builder builder = Key.newBuilder();
  for (String key : table.getKeyColumns()) {
    Object value = keyValues.get(key);
    if (!generateParameterMetaData && value == null && !keyValues.containsKey(key)) {
      throw new CloudSpannerSQLException(
          "No value supplied for key column " + key
              + ". All key columns must be specified in the WHERE-clause of a DELETE-statement.",
          Code.INVALID_ARGUMENT);
    }
    builder.appendObject(convert(value));
  }
  return builder;
}
 
Example 16
Source File: CloudSpannerStatement.java    From spanner-jdbc with MIT License 4 votes vote down vote up
@Override
public boolean execute(String sql) throws SQLException {
  String[] sqlTokens = getTokens(sql);
  CustomDriverStatement custom = getCustomDriverStatement(sqlTokens);
  if (custom != null)
    return custom.execute(sqlTokens);
  Statement statement = null;
  boolean ddl = isDDLStatement(sqlTokens);
  if (!ddl) {
    try {
      statement = CCJSqlParserUtil.parse(sanitizeSQL(sql));
    } catch (JSQLParserException | TokenMgrException e) {
      throw new CloudSpannerSQLException(
          "Error while parsing sql statement " + sql + ": " + e.getLocalizedMessage(),
          Code.INVALID_ARGUMENT, e);
    }
  }
  if (!ddl && statement instanceof Select) {
    determineForceSingleUseReadContext((Select) statement);
    if (!isForceSingleUseReadContext() && getConnection().isBatchReadOnly()) {
      List<Partition> partitions = partitionQuery(com.google.cloud.spanner.Statement.of(sql));
      currentResultSets = new ArrayList<>(partitions.size());
      for (Partition p : partitions) {
        currentResultSets
            .add(new CloudSpannerPartitionResultSet(this, getBatchReadOnlyTransaction(), p, sql));
      }
    } else {
      try (ReadContext context = getReadContext()) {
        com.google.cloud.spanner.ResultSet rs =
            context.executeQuery(com.google.cloud.spanner.Statement.of(sql));
        currentResultSets = Arrays.asList(new CloudSpannerResultSet(this, rs, sql));
        currentResultSetIndex = 0;
        lastUpdateCount = -1;
      }
    }
    return true;
  } else {
    lastUpdateCount = executeUpdate(sql);
    currentResultSetIndex = 0;
    currentResultSets = null;
    return false;
  }
}
 
Example 17
Source File: AbstractSpannerExpressionVisitorAdapter.java    From spanner-jdbc with MIT License 4 votes vote down vote up
@Override
public void visit(TimeKeyExpression timeKeyExpression) {
  throw new IllegalArgumentException(new CloudSpannerSQLException(
      "Function calls such as for example GET_TIMESTAMP() are not allowed in client side insert/update statements. Use an insert statement with a select statement instead: INSERT INTO COL1, COL2, COL3 SELECT 1, GET_TIMESTAMP(), 'test'",
      Code.INVALID_ARGUMENT));
}
 
Example 18
Source File: CloudSpannerPreparedStatement.java    From spanner-jdbc with MIT License 4 votes vote down vote up
private Mutations createMutations(String sql, boolean forceUpdate,
    boolean generateParameterMetaData) throws SQLException {
  try {
    if (getConnection().isReadOnly()) {
      throw new CloudSpannerSQLException(NO_MUTATIONS_IN_READ_ONLY_MODE_EXCEPTION,
          Code.FAILED_PRECONDITION);
    }
    if (isDDLStatement()) {
      throw new CloudSpannerSQLException(
          "Cannot create mutation for DDL statement. Expected INSERT, UPDATE or DELETE",
          Code.INVALID_ARGUMENT);
    }
    Statement statement = CCJSqlParserUtil.parse(sanitizeSQL(sql));
    if (statement instanceof Insert) {
      Insert insertStatement = (Insert) statement;
      if (generateParameterMetaData || insertStatement.getSelect() == null)
        return new Mutations(createInsertMutation(insertStatement, generateParameterMetaData));
      return new Mutations(createInsertWithSelectStatement(insertStatement, forceUpdate));
    } else if (statement instanceof Update) {
      Update updateStatement = (Update) statement;
      if (updateStatement.getSelect() != null)
        throw new CloudSpannerSQLException(
            "UPDATE statement using SELECT is not supported. Try to re-write the statement as an INSERT INTO ... SELECT A, B, C FROM TABLE WHERE ... ON DUPLICATE KEY UPDATE",
            Code.INVALID_ARGUMENT);
      if (updateStatement.getTables().size() > 1)
        throw new CloudSpannerSQLException(
            "UPDATE statement using multiple tables is not supported. Try to re-write the statement as an INSERT INTO ... SELECT A, B, C FROM TABLE WHERE ... ON DUPLICATE KEY UPDATE",
            Code.INVALID_ARGUMENT);

      if (generateParameterMetaData || isSingleRowWhereClause(
          getConnection()
              .getTable(unquoteIdentifier(updateStatement.getTables().get(0).getName())),
          updateStatement.getWhere()))
        return new Mutations(createUpdateMutation(updateStatement, generateParameterMetaData));
      // Translate into an 'INSERT ... SELECT ... ON DUPLICATE KEY
      // UPDATE'-statement
      String insertSQL = createInsertSelectOnDuplicateKeyUpdateStatement(updateStatement);
      return createMutations(insertSQL, true, false);
    } else if (statement instanceof Delete) {
      Delete deleteStatement = (Delete) statement;
      if (generateParameterMetaData || deleteStatement.getWhere() == null
          || isSingleRowWhereClause(
              getConnection().getTable(unquoteIdentifier(deleteStatement.getTable().getName())),
              deleteStatement.getWhere()))
        return new Mutations(createDeleteMutation(deleteStatement, generateParameterMetaData));
      return new Mutations(createDeleteWorker(deleteStatement));
    } else {
      throw new CloudSpannerSQLException(
          "Unrecognized or unsupported SQL-statment: Expected one of INSERT, UPDATE or DELETE. Please note that batching of prepared statements is not supported for SELECT-statements.",
          Code.INVALID_ARGUMENT);
    }
  } catch (JSQLParserException | IllegalArgumentException | TokenMgrException e) {
    throw new CloudSpannerSQLException(PARSE_ERROR + sql + ": " + e.getLocalizedMessage(),
        Code.INVALID_ARGUMENT, e);
  }
}
 
Example 19
Source File: ConnectionProperties.java    From spanner-jdbc with MIT License 4 votes vote down vote up
static ConnectionProperties parse(String url) throws SQLException {
  ConnectionProperties res = new ConnectionProperties();
  if (url != null) {
    String[] parts = url.split(":", 3);
    String[] connectionParts = parts[2].split(";");
    // Get connection properties from connection string
    for (int i = 1; i < connectionParts.length; i++) {
      String conPart = connectionParts[i].replace(" ", "");
      String conPartLower = conPart.toLowerCase();
      if (conPartLower.startsWith(PROJECT_URL_PART.toLowerCase()))
        res.project = conPart.substring(PROJECT_URL_PART.length());
      else if (conPartLower.startsWith(INSTANCE_URL_PART.toLowerCase()))
        res.instance = conPart.substring(INSTANCE_URL_PART.length());
      else if (conPartLower.startsWith(DATABASE_URL_PART.toLowerCase()))
        res.database = conPart.substring(DATABASE_URL_PART.length());
      else if (conPartLower.startsWith(KEY_FILE_URL_PART.toLowerCase()))
        res.keyFile = conPart.substring(KEY_FILE_URL_PART.length());
      else if (conPartLower.startsWith(OAUTH_ACCESS_TOKEN_URL_PART.toLowerCase()))
        res.oauthToken = conPart.substring(OAUTH_ACCESS_TOKEN_URL_PART.length());
      else if (conPartLower.startsWith(SIMULATE_PRODUCT_NAME.toLowerCase()))
        res.productName = conPart.substring(SIMULATE_PRODUCT_NAME.length());
      else if (conPartLower.startsWith(SIMULATE_PRODUCT_MAJOR_VERSION.toLowerCase()))
        res.majorVersion =
            parseInteger(conPart.substring(SIMULATE_PRODUCT_MAJOR_VERSION.length()));
      else if (conPartLower.startsWith(SIMULATE_PRODUCT_MINOR_VERSION.toLowerCase()))
        res.minorVersion =
            parseInteger(conPart.substring(SIMULATE_PRODUCT_MINOR_VERSION.length()));
      else if (conPartLower.startsWith(ALLOW_EXTENDED_MODE.toLowerCase()))
        res.allowExtendedMode = Boolean.valueOf(conPart.substring(ALLOW_EXTENDED_MODE.length()));
      else if (conPartLower.startsWith(ASYNC_DDL_OPERATIONS.toLowerCase()))
        res.asyncDdlOperations =
            Boolean.valueOf(conPart.substring(ASYNC_DDL_OPERATIONS.length()));
      else if (conPartLower.startsWith(AUTO_BATCH_DDL_OPERATIONS.toLowerCase()))
        res.autoBatchDdlOperations =
            Boolean.valueOf(conPart.substring(AUTO_BATCH_DDL_OPERATIONS.length()));
      else if (conPartLower.startsWith(REPORT_DEFAULT_SCHEMA_AS_NULL.toLowerCase()))
        res.reportDefaultSchemaAsNull =
            Boolean.valueOf(conPart.substring(REPORT_DEFAULT_SCHEMA_AS_NULL.length()));
      else if (conPartLower.startsWith(BATCH_READ_ONLY_MODE.toLowerCase()))
        res.batchReadOnlyMode = Boolean.valueOf(conPart.substring(BATCH_READ_ONLY_MODE.length()));
      else if (conPartLower.startsWith(USE_CUSTOM_HOST.toLowerCase()))
        res.useCustomHost = Boolean.valueOf(conPart.substring(USE_CUSTOM_HOST.length()));
      else
        throw new CloudSpannerSQLException("Unknown URL parameter " + conPart,
            Code.INVALID_ARGUMENT);
    }
  }
  return res;
}
 
Example 20
Source File: CloudSpannerPreparedStatement.java    From spanner-jdbc with MIT License 4 votes vote down vote up
private Mutation createInsertMutation(Insert insert, boolean generateParameterMetaData)
    throws SQLException {
  ItemsList items = insert.getItemsList();
  if (generateParameterMetaData && items == null && insert.getSelect() != null) {
    // Just initialize the parameter meta data of the select statement
    createSelectBuilder(insert.getSelect(), insert.getSelect().toString());
    return null;
  }
  if (!(items instanceof ExpressionList)) {
    throw new CloudSpannerSQLException("Insert statement must specify a list of values",
        Code.INVALID_ARGUMENT);
  }
  if (insert.getColumns() == null || insert.getColumns().isEmpty()) {
    throw new CloudSpannerSQLException("Insert statement must specify a list of column names",
        Code.INVALID_ARGUMENT);
  }
  List<Expression> expressions = ((ExpressionList) items).getExpressions();
  String table = unquoteIdentifier(insert.getTable().getFullyQualifiedName());
  getParameterStore().setTable(table);
  WriteBuilder builder;
  if (insert.isUseDuplicate()) {
    /**
     * Do an insert-or-update. BUT: Cloud Spanner does not support supplying different values for
     * the insert and update statements, meaning that only the values specified in the INSERT part
     * of the statement will be considered. Anything specified in the 'ON DUPLICATE KEY UPDATE
     * ...' statement will be ignored.
     */
    if (this.forceUpdate)
      builder = Mutation.newUpdateBuilder(table);
    else
      builder = Mutation.newInsertOrUpdateBuilder(table);
  } else {
    /**
     * Just do an insert and throw an error if a row with the specified key alread exists.
     */
    builder = Mutation.newInsertBuilder(table);
  }
  int index = 0;
  for (Column col : insert.getColumns()) {
    String columnName = unquoteIdentifier(col.getFullyQualifiedName());
    expressions.get(index).accept(new ValueBinderExpressionVisitorAdapter<>(getParameterStore(),
        builder.set(columnName), columnName));
    index++;
  }
  return builder.build();
}