diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldList.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldList.java index d3472562a..c18d25142 100644 --- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldList.java +++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/FieldList.java @@ -18,10 +18,10 @@ import com.google.api.services.bigquery.model.TableFieldSchema; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import java.io.Serializable; import java.util.AbstractList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,16 +36,28 @@ public final class FieldList extends AbstractList implements Serializable private final List fields; private final Map nameIndex; + private static class CaseInsensitiveMap extends HashMap { + @Override + public Integer put(String key, Integer value) { + return super.put(key.toLowerCase(), value); + } + + @Override + public Integer get(Object key) { + return super.get(key.toString().toLowerCase()); + } + } + private FieldList(Iterable fields) { this.fields = ImmutableList.copyOf(fields); - ImmutableMap.Builder nameIndexBuilder = ImmutableMap.builder(); + Map caseInsensitiveMap = new CaseInsensitiveMap(); int index = 0; for (Field field : fields) { - nameIndexBuilder.put(field.getName(), index); + caseInsensitiveMap.put(field.getName(), index); index++; } - this.nameIndex = nameIndexBuilder.build(); + this.nameIndex = caseInsensitiveMap; } /** diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldListTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldListTest.java index f7995ae2a..999bbf1b0 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldListTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/FieldListTest.java @@ -26,6 +26,12 @@ public class FieldListTest { private static final String FIELD_NAME1 = "StringField"; private static final String FIELD_NAME2 = "IntegerField"; private static final String FIELD_NAME3 = "RecordField"; + private static final String FIELD_NAME_CASE_INSENSITIVE1 = "stringfield"; + private static final String FIELD_NAME_CASE_INSENSITIVE2 = "integerfield"; + private static final String FIELD_NAME_CASE_INSENSITIVE3 = "recordfield"; + private static final String FIELD_NAME_CASE_INSENSITIVE4 = "stRingfiEld"; + private static final String FIELD_NAME_CASE_INSENSITIVE5 = "inTeGerField"; + private static final String FIELD_NAME_CASE_INSENSITIVE6 = "recOrdfieLd"; private static final String FIELD_NAME4 = "NonExistentField"; private static final LegacySQLTypeName FIELD_TYPE1 = LegacySQLTypeName.STRING; private static final LegacySQLTypeName FIELD_TYPE2 = LegacySQLTypeName.INTEGER; @@ -61,6 +67,12 @@ public void testGetByName() { assertEquals(fieldSchema1, fieldsSchema.get(FIELD_NAME1)); assertEquals(fieldSchema2, fieldsSchema.get(FIELD_NAME2)); assertEquals(fieldSchema3, fieldsSchema.get(FIELD_NAME3)); + assertEquals(fieldSchema1, fieldsSchema.get(FIELD_NAME_CASE_INSENSITIVE1)); + assertEquals(fieldSchema2, fieldsSchema.get(FIELD_NAME_CASE_INSENSITIVE2)); + assertEquals(fieldSchema3, fieldsSchema.get(FIELD_NAME_CASE_INSENSITIVE3)); + assertEquals(fieldSchema1, fieldsSchema.get(FIELD_NAME_CASE_INSENSITIVE4)); + assertEquals(fieldSchema2, fieldsSchema.get(FIELD_NAME_CASE_INSENSITIVE5)); + assertEquals(fieldSchema3, fieldsSchema.get(FIELD_NAME_CASE_INSENSITIVE6)); assertEquals(3, fieldsSchema.size()); @@ -95,8 +107,16 @@ public void testGetRecordSchema() { assertEquals(2, fieldSchema3.getSubFields().size()); assertEquals(fieldSchema1, fieldSchema3.getSubFields().get(FIELD_NAME1)); assertEquals(fieldSchema2, fieldSchema3.getSubFields().get(FIELD_NAME2)); + assertEquals(fieldSchema1, fieldSchema3.getSubFields().get(FIELD_NAME_CASE_INSENSITIVE1)); + assertEquals(fieldSchema2, fieldSchema3.getSubFields().get(FIELD_NAME_CASE_INSENSITIVE2)); + assertEquals(fieldSchema1, fieldSchema3.getSubFields().get(FIELD_NAME_CASE_INSENSITIVE4)); + assertEquals(fieldSchema2, fieldSchema3.getSubFields().get(FIELD_NAME_CASE_INSENSITIVE5)); assertEquals(0, fieldSchema3.getSubFields().getIndex(FIELD_NAME1)); assertEquals(1, fieldSchema3.getSubFields().getIndex(FIELD_NAME2)); + assertEquals(0, fieldSchema3.getSubFields().getIndex(FIELD_NAME_CASE_INSENSITIVE1)); + assertEquals(1, fieldSchema3.getSubFields().getIndex(FIELD_NAME_CASE_INSENSITIVE2)); + assertEquals(0, fieldSchema3.getSubFields().getIndex(FIELD_NAME_CASE_INSENSITIVE4)); + assertEquals(1, fieldSchema3.getSubFields().getIndex(FIELD_NAME_CASE_INSENSITIVE5)); assertEquals(fieldSchema1, fieldSchema3.getSubFields().get(0)); assertEquals(fieldSchema2, fieldSchema3.getSubFields().get(1)); } diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index a12bd59d2..d7497b918 100644 --- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -1532,6 +1532,34 @@ public void testQuery() throws InterruptedException { assertNotNull(statistics.getQueryPlan()); } + @Test + public void testQueryCaseInsensitiveSchemaFieldByGetName() throws InterruptedException { + String query = "SELECT TimestampField, StringField, BooleanField FROM " + TABLE_ID.getTable(); + QueryJobConfiguration config = + QueryJobConfiguration.newBuilder(query).setDefaultDataset(DatasetId.of(DATASET)).build(); + Job job = bigquery.create(JobInfo.of(JobId.of(), config)); + + TableResult result = job.getQueryResults(); + assertEquals(QUERY_RESULT_SCHEMA, result.getSchema()); + int rowCount = 0; + for (FieldValueList row : result.getValues()) { + FieldValue timestampCell = row.get(0); + assertEquals(timestampCell, row.get("TimestampField")); + assertEquals(timestampCell, row.get("timestampfield")); + assertEquals(timestampCell, row.get("timeStampfIeld")); + FieldValue stringCell = row.get(1); + assertEquals(stringCell, row.get("StringField")); + assertEquals(stringCell, row.get("stringfield")); + assertEquals(stringCell, row.get("sTrinGfield")); + FieldValue booleanCell = row.get(2); + assertEquals(booleanCell, row.get("BooleanField")); + assertEquals(booleanCell, row.get("booleanfield")); + assertEquals(booleanCell, row.get("booLeanfielD")); + rowCount++; + } + assertEquals(2, rowCount); + } + @Test public void testFastSQLQuery() throws InterruptedException { String query =