Skip to content

Commit

Permalink
feat: Support RANGE schema (#3043)
Browse files Browse the repository at this point in the history
* feat: Add support for creating tables with range type schema

* feat: Add support for creating tables with range type schema

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* feat: Use location in BigQueryOption as the default for query

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
PhongChuong and gcf-owl-bot[bot] committed Jan 5, 2024
1 parent 7a1bbd2 commit febfc1f
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 2 deletions.
Expand Up @@ -64,6 +64,7 @@ public TableFieldSchema apply(Field field) {
private final Long precision;
private final String defaultValueExpression;
private final String collation;
private final FieldElementType rangeElementType;

/**
* Mode for a BigQuery Table field. {@link Mode#NULLABLE} fields can be set to {@code null},
Expand All @@ -89,6 +90,7 @@ public static final class Builder {
private Long precision;
private String defaultValueExpression;
private String collation;
private FieldElementType rangeElementType;

private Builder() {}

Expand All @@ -104,6 +106,7 @@ private Builder(Field field) {
this.precision = field.precision;
this.defaultValueExpression = field.defaultValueExpression;
this.collation = field.collation;
this.rangeElementType = field.rangeElementType;
}

/**
Expand Down Expand Up @@ -292,6 +295,12 @@ public Builder setCollation(String collation) {
return this;
}

/** Optional. Field range element type can be set only when the type of field is RANGE. */
public Builder setRangeElementType(FieldElementType rangeElementType) {
this.rangeElementType = rangeElementType;
return this;
}

/** Creates a {@code Field} object. */
public Field build() {
return new Field(this);
Expand All @@ -310,6 +319,7 @@ private Field(Builder builder) {
this.precision = builder.precision;
this.defaultValueExpression = builder.defaultValueExpression;
this.collation = builder.collation;
this.rangeElementType = builder.rangeElementType;
}

/** Returns the field name. */
Expand Down Expand Up @@ -369,6 +379,11 @@ public String getCollation() {
return collation;
}

/** Return the range element type the field. */
public FieldElementType getRangeElementType() {
return rangeElementType;
}

/**
* Returns the list of sub-fields if {@link #getType()} is a {@link LegacySQLTypeName#RECORD}.
* Returns {@code null} otherwise.
Expand All @@ -395,12 +410,13 @@ public String toString() {
.add("precision", precision)
.add("defaultValueExpression", defaultValueExpression)
.add("collation", collation)
.add("rangeElementType", rangeElementType)
.toString();
}

@Override
public int hashCode() {
return Objects.hash(name, type, mode, description, policyTags);
return Objects.hash(name, type, mode, description, policyTags, rangeElementType);
}

@Override
Expand Down Expand Up @@ -484,6 +500,9 @@ TableFieldSchema toPb() {
if (collation != null) {
fieldSchemaPb.setCollation(collation);
}
if (rangeElementType != null) {
fieldSchemaPb.setRangeElementType(rangeElementType.toPb());
}
return fieldSchemaPb;
}

Expand Down Expand Up @@ -519,6 +538,10 @@ static Field fromPb(TableFieldSchema fieldSchemaPb) {
if (fieldSchemaPb.getCollation() != null) {
fieldBuilder.setCollation(fieldSchemaPb.getCollation());
}
if (fieldSchemaPb.getRangeElementType() != null) {
fieldBuilder.setRangeElementType(
FieldElementType.fromPb(fieldSchemaPb.getRangeElementType()));
}
return fieldBuilder.build();
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.bigquery;

import com.google.api.services.bigquery.model.TableFieldSchema;
import com.google.auto.value.AutoValue;
import java.io.Serializable;
import javax.annotation.Nullable;

@AutoValue
public abstract class FieldElementType implements Serializable {

private static final long serialVersionUID = 1L;

/**
* The subtype of the RANGE, if the field type is RANGE.
*
* @return value or {@code null} for none
*/
@Nullable
public abstract String getType();

public abstract FieldElementType.Builder toBuilder();

@AutoValue.Builder
public abstract static class Builder {

public abstract FieldElementType.Builder setType(String type);

public abstract FieldElementType build();
}

public static Builder newBuilder() {
return new AutoValue_FieldElementType.Builder();
}

TableFieldSchema.RangeElementType toPb() {
TableFieldSchema.RangeElementType rangeElementTypePb = new TableFieldSchema.RangeElementType();
rangeElementTypePb.setType(getType());
return rangeElementTypePb;
}

static FieldElementType fromPb(TableFieldSchema.RangeElementType rangeElementTypePb) {
// Treat a FieldElementType message without a Type subfield as invalid.
if (rangeElementTypePb.getType() != null) {
return newBuilder().setType(rangeElementTypePb.getType()).build();
}
return null;
}
}
Expand Up @@ -100,6 +100,10 @@ public LegacySQLTypeName apply(String constant) {
public static final LegacySQLTypeName INTERVAL =
type.createAndRegister("INTERVAL").setStandardType(StandardSQLTypeName.INTERVAL);

/** Represents a contiguous range of values. */
public static final LegacySQLTypeName RANGE =
type.createAndRegister("RANGE").setStandardType(StandardSQLTypeName.RANGE);

private static Map<StandardSQLTypeName, LegacySQLTypeName> standardToLegacyMap = new HashMap<>();

static {
Expand Down
Expand Up @@ -60,5 +60,7 @@ public enum StandardSQLTypeName {
/** Represents JSON data. */
JSON,
/** Represents duration or amount of time. */
INTERVAL
INTERVAL,
/** Represents a contiguous range of values. */
RANGE
}
@@ -0,0 +1,46 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.bigquery;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class FieldElementTypeTest {
private static final FieldElementType FIELD_ELEMENT_TYPE =
FieldElementType.newBuilder().setType("DATE").build();

@Test
public void testToBuilder() {
compareFieldElementType(FIELD_ELEMENT_TYPE, FIELD_ELEMENT_TYPE.toBuilder().build());
}

@Test
public void testBuilder() {
assertEquals("DATE", FIELD_ELEMENT_TYPE.getType());
}

@Test
public void testFromAndPb() {
assertEquals(FIELD_ELEMENT_TYPE, FieldElementType.fromPb(FIELD_ELEMENT_TYPE.toPb()));
}

private void compareFieldElementType(FieldElementType expected, FieldElementType value) {
assertEquals(expected.getType(), value.getType());
assertEquals(expected.hashCode(), value.hashCode());
assertEquals(expected.toString(), value.toString());
}
}
Expand Up @@ -72,6 +72,7 @@
import com.google.cloud.bigquery.ExtractJobConfiguration;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Field.Mode;
import com.google.cloud.bigquery.FieldElementType;
import com.google.cloud.bigquery.FieldList;
import com.google.cloud.bigquery.FieldValue;
import com.google.cloud.bigquery.FieldValue.Attribute;
Expand Down Expand Up @@ -1246,6 +1247,25 @@ public void testIntervalType() throws InterruptedException {
}
}

@Test
public void testRangeType() throws InterruptedException {
String tableName = "test_create_table_rangetype";
TableId tableId = TableId.of(DATASET, tableName);
Schema schema =
Schema.of(
Field.newBuilder("rangeField", StandardSQLTypeName.RANGE)
.setRangeElementType(FieldElementType.newBuilder().setType("DATETIME").build())
.build());
StandardTableDefinition standardTableDefinition = StandardTableDefinition.of(schema);
try {
// Create a table with a RANGE column.
Table createdTable = bigquery.create(TableInfo.of(tableId, standardTableDefinition));
assertNotNull(createdTable);
} finally {
assertTrue(bigquery.delete(tableId));
}
}

@Test
public void testCreateTableWithConstraints() {
String tableName = "test_create_table_with_constraints";
Expand Down

0 comments on commit febfc1f

Please sign in to comment.