Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions java-bigquery-jdbc/docs/USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ String url = "jdbc:bigquery://https://bigquery.googleapis.com:443"
| :--- | :---: | :--- |
| `EnableSession` | `false` | Enables multi-statement session creation and transaction support (`BEGIN`, `COMMIT`, `ROLLBACK`). |

### Data Types & Extended Precision Properties

| Property Name | Default Value | Description |
| :--- | :---: | :--- |
| `EnableTimestampPicos` | `false` | Enables 12-digit picosecond precision for `TIMESTAMP(12)` data types. When enabled, `TIMESTAMP(12)` columns are retrieved with 12 fractional digits formatted in UTC (`YYYY-MM-DD HH:MM:SS.ffffffffffff`) via `getString()` and `getObject()`, typed as `Types.VARCHAR` (`12`) with type name `"TIMESTAMP_PICOSECONDS"`. Picosecond precision is incompatible with Legacy SQL (`QueryDialect=BIG_QUERY`). |

### High-Throughput Storage & Write API Properties

| Property Name | Default Value | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
BigQueryJdbcUrlUtility.KMS_KEY_NAME_PROPERTY_NAME,
BigQueryJdbcUrlUtility.QUERY_PROPERTIES_NAME,
BigQueryJdbcUrlUtility.ENABLE_SESSION_PROPERTY_NAME,
BigQueryJdbcUrlUtility.ENABLE_TIMESTAMP_PICOS_PROPERTY_NAME,
BigQueryJdbcUrlUtility.LOG_LEVEL_PROPERTY_NAME,
BigQueryJdbcUrlUtility.LOG_PATH_PROPERTY_NAME,
BigQueryJdbcUrlUtility.OAUTH_TYPE_PROPERTY_NAME,
Expand Down Expand Up @@ -186,6 +187,7 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
int highThroughputMinTableSize;
int highThroughputActivationRatio;
boolean enableSession;
boolean enableTimestampPicos;
boolean enableProjectDiscovery;
private List<String> discoveredProjectsCache;
boolean unsupportedHTAPIFallback;
Expand Down Expand Up @@ -357,6 +359,7 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
this.sslTrustStoreProvider,
this.connectionClassName);
this.enableSession = ds.getEnableSession();
this.enableTimestampPicos = ds.getEnableTimestampPicos();
Comment thread
keshavdandeva marked this conversation as resolved.
this.unsupportedHTAPIFallback = ds.getUnsupportedHTAPIFallback();
this.maxResults = ds.getMaxResults();
Map<String, String> queryPropertiesMap = ds.getQueryProperties();
Expand Down Expand Up @@ -719,6 +722,10 @@ boolean isSessionEnabled() {
return this.enableSession;
}

boolean isEnableTimestampPicos() {
return this.enableTimestampPicos;
}

boolean isUnsupportedHTAPIFallback() {
return this.unsupportedHTAPIFallback;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ protected boolean removeEldestEntry(Map.Entry<String, Map<String, String>> eldes
static final String LOG_LEVEL_ENV_VAR = "BIGQUERY_JDBC_LOG_LEVEL";
static final String LOG_PATH_ENV_VAR = "BIGQUERY_JDBC_LOG_PATH";
static final String ENABLE_SESSION_PROPERTY_NAME = "EnableSession";
static final String ENABLE_TIMESTAMP_PICOS_PROPERTY_NAME = "EnableTimestampPicos";
static final boolean DEFAULT_ENABLE_TIMESTAMP_PICOS_VALUE = false;
static final String DEFAULT_LOG_PATH = "";
static final String USE_QUERY_CACHE_PROPERTY_NAME = "UseQueryCache";
static final boolean DEFAULT_USE_QUERY_CACHE = true;
Expand Down Expand Up @@ -446,6 +448,14 @@ protected boolean removeEldestEntry(Map.Entry<String, Map<String, String>> eldes
+ " transactions. Disabled by default.")
.setDefaultValue(String.valueOf(DEFAULT_ENABLE_SESSION_VALUE))
.build(),
BigQueryConnectionProperty.newBuilder()
.setName(ENABLE_TIMESTAMP_PICOS_PROPERTY_NAME)
.setDescription(
"Enables picosecond precision for TIMESTAMP data types. When enabled,"
+ " TIMESTAMP(12) columns are retrieved with 12-digit picosecond"
+ " precision formatted in UTC. Disabled by default.")
.setDefaultValue(String.valueOf(DEFAULT_ENABLE_TIMESTAMP_PICOS_VALUE))
.build(),
BigQueryConnectionProperty.newBuilder()
.setName(LOG_LEVEL_PROPERTY_NAME)
.setDescription(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class BigQuerySettings {
private final boolean unsupportedHTAPIFallback;

private final boolean enableSession;
private final boolean enableTimestampPicos;

private final ConnectionProperty sessionInfoConnectionProperty;

Expand Down Expand Up @@ -120,6 +121,7 @@ private BigQuerySettings(Builder builder) {
this.maxResultPerPage = builder.maxResultPerPage;
this.defaultDataset = builder.defaultDataset;
this.enableSession = builder.enableSession;
this.enableTimestampPicos = builder.enableTimestampPicos;
this.unsupportedHTAPIFallback = builder.unsupportedHTAPIFallback;
this.sessionInfoConnectionProperty = builder.sessionInfoConnectionProperty;
this.useWriteAPI = builder.useWriteAPI;
Expand Down Expand Up @@ -171,6 +173,15 @@ boolean isEnableSession() {
return enableSession;
}

/**
* Returns whether picosecond precision is enabled for TIMESTAMP data types.
*
* @return true if picosecond precision is enabled, false otherwise.
*/
boolean isEnableTimestampPicos() {
return enableTimestampPicos;
}

/**
* When the connector uses fetch workflows not supported on the High-Throughput API, this option
* specifies whether the connector falls back to the REST API or returns an error. By default it
Expand Down Expand Up @@ -476,6 +487,7 @@ static final class Builder {
private int highThroughputMinTableSize;
private int highThroughputActivationRatio;
private boolean enableSession;
private boolean enableTimestampPicos;
private boolean unsupportedHTAPIFallback;
private ConnectionProperty sessionInfoConnectionProperty;
private boolean useQueryCache;
Expand Down Expand Up @@ -516,6 +528,7 @@ private Builder(BigQuerySettings querySettings) {
this.highThroughputMinTableSize = querySettings.getHighThroughputMinTableSize();
this.highThroughputActivationRatio = querySettings.getHighThroughputActivationRatio();
this.enableSession = querySettings.isEnableSession();
this.enableTimestampPicos = querySettings.isEnableTimestampPicos();
this.unsupportedHTAPIFallback = querySettings.isUnsupportedHTAPIFallback();
this.sessionInfoConnectionProperty = querySettings.getSessionInfoConnectionProperty();
this.useQueryCache = querySettings.getUseQueryCache();
Expand Down Expand Up @@ -608,6 +621,15 @@ Builder setEnableSession(boolean enableSession) {
return this;
}

/**
* Setting true enables 12-digit picosecond precision for TIMESTAMP(12) columns. Disabled by
* default.
*/
Builder setEnableTimestampPicos(boolean enableTimestampPicos) {
this.enableTimestampPicos = enableTimestampPicos;
return this;
}

/**
* When the connector uses fetch workflows not supported on the High-Throughput API, this option
* specifies whether the connector falls back to the REST API or returns an error. By default it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ private BigQuerySettings generateBigQuerySettings() {
querySettings.setUseWriteAPI(this.connection.isEnableWriteAPI());
querySettings.setWriteAPIActivationRowCount(this.connection.getWriteAPIActivationRowCount());
querySettings.setWriteAPIAppendRowCount(this.connection.getWriteAPIAppendRowCount());
querySettings.setEnableTimestampPicos(this.connection.isEnableTimestampPicos());

return querySettings.build();
}
Expand Down Expand Up @@ -1534,6 +1535,10 @@ private boolean getUseLegacySql() {
QueryDialectType.valueOf(this.querySettings.getQueryDialect()));
}

boolean isEnableTimestampPicos() {
return this.querySettings.isEnableTimestampPicos();
}
Comment thread
keshavdandeva marked this conversation as resolved.

private void checkIfDatasetExistElseCreate(String datasetName) {
Dataset dataset = bigQuery.getDataset(DatasetId.of(datasetName));
if (dataset == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class DataSource implements javax.sql.DataSource {
private Map<String, String> queryProperties;
private String logLevel;
private Boolean enableSession;
private Boolean enableTimestampPicos;
private String logPath;
private String gcpTelemetryProjectId;
private String gcpTelemetryCredentials;
Expand Down Expand Up @@ -180,6 +181,12 @@ public class DataSource implements javax.sql.DataSource {
ds.setEnableSession(
BigQueryJdbcUrlUtility.convertIntToBoolean(
val, BigQueryJdbcUrlUtility.ENABLE_SESSION_PROPERTY_NAME)))
.put(
BigQueryJdbcUrlUtility.ENABLE_TIMESTAMP_PICOS_PROPERTY_NAME,
(ds, val) ->
ds.setEnableTimestampPicos(
BigQueryJdbcUrlUtility.convertIntToBoolean(
val, BigQueryJdbcUrlUtility.ENABLE_TIMESTAMP_PICOS_PROPERTY_NAME)))
.put(BigQueryJdbcUrlUtility.LOG_LEVEL_PROPERTY_NAME, DataSource::setLogLevel)
.put(BigQueryJdbcUrlUtility.LOG_PATH_PROPERTY_NAME, DataSource::setLogPath)
.put(
Expand Down Expand Up @@ -490,6 +497,11 @@ Properties createProperties() {
connectionProperties.setProperty(
BigQueryJdbcUrlUtility.ENABLE_SESSION_PROPERTY_NAME, String.valueOf(this.enableSession));
}
if (this.enableTimestampPicos != null) {
connectionProperties.setProperty(
BigQueryJdbcUrlUtility.ENABLE_TIMESTAMP_PICOS_PROPERTY_NAME,
String.valueOf(this.enableTimestampPicos));
}
if (this.logLevel != null) {
connectionProperties.setProperty(
BigQueryJdbcUrlUtility.LOG_LEVEL_PROPERTY_NAME, this.logLevel);
Expand Down Expand Up @@ -935,6 +947,16 @@ public void setEnableSession(Boolean enableSession) {
this.enableSession = enableSession;
}

public Boolean getEnableTimestampPicos() {
return enableTimestampPicos != null
? enableTimestampPicos
: BigQueryJdbcUrlUtility.DEFAULT_ENABLE_TIMESTAMP_PICOS_VALUE;
}

public void setEnableTimestampPicos(Boolean enableTimestampPicos) {
this.enableTimestampPicos = enableTimestampPicos;
}

public String getLogLevel() {
return logLevel;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -819,4 +819,19 @@ public void testUserSuppliedSessionId() throws Exception {
"user_supplied_session_999", connection.getSessionInfoConnectionProperty().getValue());
}
}

@Test
public void testEnableTimestampPicosDefault() throws Exception {
try (BigQueryConnection connection = new BigQueryConnection(BASE_URL)) {
assertFalse(connection.isEnableTimestampPicos());
}
}

@Test
public void testEnableTimestampPicosConfigured() throws Exception {
String url = BASE_URL + "EnableTimestampPicos=1;";
try (BigQueryConnection connection = new BigQueryConnection(url)) {
assertTrue(connection.isEnableTimestampPicos());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,23 @@ public void testParseDefaultDataset_invalidFormats() {
BigQueryJdbcRuntimeException.class,
() -> BigQueryJdbcUrlUtility.parseDefaultDataset(" : "));
}

@Test
public void testParseEnableTimestampPicos() {
String url =
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;"
+ "ProjectId=MyBigQueryProject;"
+ "EnableTimestampPicos=1";

String result = BigQueryJdbcUrlUtility.parseUriProperty(url, "EnableTimestampPicos");
assertThat(result).isEqualTo("1");

String url2 =
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;"
+ "ProjectId=MyBigQueryProject;"
+ "EnableTimestampPicos=0";

String result2 = BigQueryJdbcUrlUtility.parseUriProperty(url2, "EnableTimestampPicos");
assertThat(result2).isEqualTo("0");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1159,4 +1159,11 @@ public void testNullStatementTypeInTableResultFallsBackToGetJobWithoutDryRun() t
verify(bigquery, Mockito.times(1)).getJob(eq(this.jobId));
verify(bigquery, Mockito.never()).create(any(JobInfo.class));
}

@Test
public void testEnableTimestampPicosPropagation() {
doReturn(true).when(bigQueryConnection).isEnableTimestampPicos();
BigQueryStatement statement = new BigQueryStatement(bigQueryConnection);
assertTrue(statement.isEnableTimestampPicos());
}
}
Loading