@@ -17,7 +17,7 @@ import {
1717 SASProtocol ,
1818 generateBlobSASQueryParameters ,
1919} from '@azure/storage-blob' ;
20- import { DriverCapabilities , QueryColumnsResult , QueryOptions , QuerySchemasResult , QueryTablesResult , UnloadOptions } from '@cubejs-backend/base-driver' ;
20+ import { DriverCapabilities , QueryColumnsResult , QueryOptions , QuerySchemasResult , QueryTablesResult , UnloadOptions , GenericDataBaseType } from '@cubejs-backend/base-driver' ;
2121import {
2222 JDBCDriver ,
2323 JDBCDriverConfiguration ,
@@ -99,7 +99,13 @@ type ShowDatabasesRow = {
9999 databaseName : string ,
100100} ;
101101
102+ type ColumnInfo = {
103+ name : any ;
104+ type : GenericDataBaseType ;
105+ } ;
106+
102107const DatabricksToGenericType : Record < string , string > = {
108+ binary : 'hll_datasketches' ,
103109 'decimal(10,0)' : 'bigint' ,
104110} ;
105111
@@ -537,8 +543,9 @@ export class DatabricksDriver extends JDBCDriver {
537543 public async queryColumnTypes (
538544 sql : string ,
539545 params ?: unknown [ ]
540- ) : Promise < { name : any ; type : string ; } [ ] > {
546+ ) : Promise < ColumnInfo [ ] > {
541547 const result = [ ] ;
548+
542549 // eslint-disable-next-line camelcase
543550 const response = await this . query < { col_name : string ; data_type : string } > (
544551 `DESCRIBE QUERY ${ sql } ` ,
@@ -631,7 +638,7 @@ export class DatabricksDriver extends JDBCDriver {
631638 private async unloadWithSql ( tableFullName : string , sql : string , params : unknown [ ] ) {
632639 const types = await this . queryColumnTypes ( sql , params ) ;
633640
634- await this . createExternalTableFromSql ( tableFullName , sql , params ) ;
641+ await this . createExternalTableFromSql ( tableFullName , sql , params , types ) ;
635642
636643 return types ;
637644 }
@@ -641,9 +648,8 @@ export class DatabricksDriver extends JDBCDriver {
641648 */
642649 private async unloadWithTable ( tableFullName : string ) {
643650 const types = await this . tableColumnTypes ( tableFullName ) ;
644- const columns = types . map ( t => t . name ) . join ( ', ' ) ;
645651
646- await this . createExternalTableFromTable ( tableFullName , columns ) ;
652+ await this . createExternalTableFromTable ( tableFullName , types ) ;
647653
648654 return types ;
649655 }
@@ -735,14 +741,17 @@ export class DatabricksDriver extends JDBCDriver {
735741 } ,
736742 region : this . config . awsRegion ,
737743 } ) ;
744+
738745 const url = new URL ( pathname ) ;
739746 const list = await client . listObjectsV2 ( {
740747 Bucket : url . host ,
741748 Prefix : url . pathname . slice ( 1 ) ,
742749 } ) ;
750+
743751 if ( list . Contents === undefined ) {
744752 throw new Error ( `No content in specified path: ${ pathname } ` ) ;
745753 }
754+
746755 const csvFile = await Promise . all (
747756 list . Contents
748757 . filter ( file => file . Key && / .c s v $ / i. test ( file . Key ) )
@@ -758,9 +767,23 @@ export class DatabricksDriver extends JDBCDriver {
758767 throw new Error ( 'No CSV files were exported to the specified bucket. ' +
759768 'Please check your export bucket configuration.' ) ;
760769 }
770+
761771 return csvFile ;
762772 }
763773
774+ protected generateTableColumnsForExport ( columns : ColumnInfo [ ] ) : string {
775+ const wrapped = columns . map ( ( c ) => {
776+ if ( c . type === 'hll_datasketches' ) {
777+ // [UNSUPPORTED_DATA_TYPE_FOR_DATASOURCE] The CSV datasource doesn't support type \"BINARY\". SQLSTATE: 0A000
778+ return `base64(${ c . name } )` ;
779+ } else {
780+ return c . name ;
781+ }
782+ } ) ;
783+
784+ return wrapped . join ( ', ' ) ;
785+ }
786+
764787 /**
765788 * Saves specified query to the configured bucket. This requires Databricks
766789 * cluster to be configured.
@@ -778,14 +801,20 @@ export class DatabricksDriver extends JDBCDriver {
778801 * `fs.s3a.access.key <aws-access-key>`
779802 * `fs.s3a.secret.key <aws-secret-key>`
780803 */
781- private async createExternalTableFromSql ( tableFullName : string , sql : string , params : unknown [ ] ) {
804+ private async createExternalTableFromSql ( tableFullName : string , sql : string , params : unknown [ ] , columns : ColumnInfo [ ] ) {
805+ let select = sql ;
806+
807+ if ( columns . find ( ( column ) => column . type === 'hll_datasketches' ) ) {
808+ select = `SELECT ${ this . generateTableColumnsForExport ( columns ) } FROM (${ sql } )` ;
809+ }
810+
782811 try {
783812 await this . query (
784813 `
785814 CREATE TABLE ${ tableFullName }
786815 USING CSV LOCATION '${ this . config . exportBucketMountDir || this . config . exportBucket } /${ tableFullName } .csv'
787816 OPTIONS (escape = '"')
788- AS (${ sql } );
817+ AS (${ select } );
789818 ` ,
790819 params ,
791820 ) ;
@@ -811,14 +840,14 @@ export class DatabricksDriver extends JDBCDriver {
811840 * `fs.s3a.access.key <aws-access-key>`
812841 * `fs.s3a.secret.key <aws-secret-key>`
813842 */
814- private async createExternalTableFromTable ( tableFullName : string , columns : string ) {
843+ private async createExternalTableFromTable ( tableFullName : string , columns : ColumnInfo [ ] ) {
815844 try {
816845 await this . query (
817846 `
818847 CREATE TABLE _${ tableFullName }
819848 USING CSV LOCATION '${ this . config . exportBucketMountDir || this . config . exportBucket } /${ tableFullName } .csv'
820849 OPTIONS (escape = '"')
821- AS SELECT ${ columns } FROM ${ tableFullName }
850+ AS SELECT ${ this . generateTableColumnsForExport ( columns ) } FROM ${ tableFullName }
822851 ` ,
823852 [ ] ,
824853 ) ;
0 commit comments