private IndexRequest prepareInsert( DocTableInfo tableInfo, ShardUpsertRequest request, ShardUpsertRequest.Item item) throws IOException { List<GeneratedReferenceInfo> generatedReferencesWithValue = new ArrayList<>(); BytesReference source; if (request.isRawSourceInsert()) { assert item.insertValues().length > 0 : "empty insert values array"; source = new BytesArray((BytesRef) item.insertValues()[0]); } else { XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); for (int i = 0; i < item.insertValues().length; i++) { Reference ref = request.insertColumns()[i]; if (ref.info().granularity() == RowGranularity.DOC) { // don't include values for partitions in the _source // ideally columns with partition granularity shouldn't be part of the request builder.field(ref.ident().columnIdent().fqn(), item.insertValues()[i]); if (ref.info() instanceof GeneratedReferenceInfo) { generatedReferencesWithValue.add((GeneratedReferenceInfo) ref.info()); } } } source = builder.bytes(); } int generatedColumnSize = 0; for (GeneratedReferenceInfo generatedReferenceInfo : tableInfo.generatedColumns()) { if (!tableInfo.partitionedByColumns().contains(generatedReferenceInfo)) { generatedColumnSize++; } } int numMissingGeneratedColumns = generatedColumnSize - generatedReferencesWithValue.size(); if (numMissingGeneratedColumns > 0 || (generatedReferencesWithValue.size() > 0 && request.validateGeneratedColumns())) { // we need to evaluate some generated column expressions Map<String, Object> sourceMap = processGeneratedColumnsOnInsert( tableInfo, request.insertColumns(), item.insertValues(), request.isRawSourceInsert(), request.validateGeneratedColumns()); source = XContentFactory.jsonBuilder().map(sourceMap).bytes(); } IndexRequest indexRequest = Requests.indexRequest(request.index()) .type(request.type()) .id(item.id()) .routing(request.routing()) .source(source) .create(!request.overwriteDuplicates()) .operationThreaded(false); if (logger.isTraceEnabled()) { logger.trace( "Inserting document with id {}, source: {}", item.id(), indexRequest.source().toUtf8()); } return indexRequest; }
@Test public void testUpdateAssignmentConvertableType() throws Exception { UpdateAnalyzedStatement.NestedAnalyzedStatement statement = analyze("update users set other_id=9.9").nestedStatements().get(0); Reference ref = statement.assignments().keySet().iterator().next(); assertThat(ref, not(instanceOf(DynamicReference.class))); assertEquals(DataTypes.LONG, ref.info().type()); Symbol value = statement.assignments().entrySet().iterator().next().getValue(); assertThat(value, isLiteral(9L)); }
@Test public void testUpdateAssignmentNestedDynamicColumn() throws Exception { UpdateAnalyzedStatement.NestedAnalyzedStatement statement = analyze("update users set details['arms']=3").nestedStatements().get(0); assertThat(statement.assignments().size(), is(1)); Reference ref = statement.assignments().keySet().iterator().next(); assertThat(ref, instanceOf(DynamicReference.class)); Assert.assertEquals(DataTypes.LONG, ref.info().type()); assertThat(ref.info().ident().columnIdent().isColumn(), is(false)); assertThat(ref.info().ident().columnIdent().fqn(), is("details.arms")); }
@Nullable @Override public Object referenceValue(Reference reference) { if (updatedColumnValues == null) { return super.referenceValue(reference); } Object value = updatedColumnValues.get(reference.ident().columnIdent().fqn()); if (value == null && !reference.ident().isColumn()) { value = XContentMapValues.extractValue( reference.ident().columnIdent().fqn(), updatedColumnValues); } return reference.valueType().value(value); }
@Test public void testUpdateAssignments() throws Exception { UpdateAnalyzedStatement statement = analyze("update users set name='Trillian'"); UpdateAnalyzedStatement.NestedAnalyzedStatement statement1 = statement.nestedStatements().get(0); assertThat(statement1.assignments().size(), is(1)); assertThat( ((DocTableRelation) statement.sourceRelation()).tableInfo().ident(), is(new TableIdent(Schemas.DEFAULT_SCHEMA_NAME, "users"))); Reference ref = statement1.assignments().keySet().iterator().next(); assertThat(ref.info().ident().tableIdent().name(), is("users")); assertThat(ref.info().ident().columnIdent().name(), is("name")); assertTrue(statement1.assignments().containsKey(ref)); Symbol value = statement1.assignments().entrySet().iterator().next().getValue(); assertThat(value, isLiteral("Trillian")); }