@@ -34,6 +34,19 @@ const (
34
34
deleteTableSQLBulkArrayDateTimeTimestamp = "drop table if exists test_bulk_array_DateTimeTimestamp"
35
35
insertSQLBulkArrayDateTimeTimestamp = "insert into test_bulk_array_DateTimeTimestamp values(?, ?, ?, ?, ?)"
36
36
selectAllSQLBulkArrayDateTimeTimestamp = "select * from test_bulk_array_DateTimeTimestamp ORDER BY 1"
37
+
38
+ enableFeatureMaxLOBSize = "ALTER SESSION SET FEATURE_INCREASED_MAX_LOB_SIZE_IN_MEMORY='ENABLED'"
39
+ unsetFeatureMaxLOBSize = "ALTER SESSION UNSET FEATURE_INCREASED_MAX_LOB_SIZE_IN_MEMORY"
40
+
41
+ // For max LOB size tests
42
+ // maxLOBSize = 128 * 1024 * 1024 // new max LOB size
43
+ maxLOBSize = 16 * 1024 * 1024 // current max LOB size
44
+ largeSize = maxLOBSize / 2
45
+ mediumSize = largeSize / 2
46
+ originSize = 16 * 1024 * 1024
47
+ smallSize = 16
48
+ // range to use for generating random numbers
49
+ lobRandomRange = 100000
37
50
)
38
51
39
52
func TestBindingFloat64 (t * testing.T ) {
@@ -975,6 +988,11 @@ func TestVariousBindingModes(t *testing.T) {
975
988
{"timestamp_ntzAndTypedNullTime" , "timestamp_ntz" , TypedNullTime {sql.NullTime {}, TimestampNTZType }, true },
976
989
{"timestamp_ltzAndTypedNullTime" , "timestamp_ltz" , TypedNullTime {sql.NullTime {}, TimestampLTZType }, true },
977
990
{"timestamp_tzAndTypedNullTime" , "timestamp_tz" , TypedNullTime {sql.NullTime {}, TimestampTZType }, true },
991
+ {"LOBSmallSize" , fmt .Sprintf ("varchar(%v)" , smallSize ), randomString (smallSize ), false },
992
+ {"LOBOriginSize" , fmt .Sprintf ("varchar(%v)" , originSize ), randomString (originSize ), false },
993
+ {"LOBMediumSize" , fmt .Sprintf ("varchar(%v)" , mediumSize ), randomString (mediumSize ), false },
994
+ {"LOBLargeSize" , fmt .Sprintf ("varchar(%v)" , largeSize ), randomString (largeSize ), false },
995
+ {"LOBMaxSize" , fmt .Sprintf ("varchar(%v)" , maxLOBSize ), randomString (maxLOBSize ), false },
978
996
}
979
997
980
998
bindingModes := []struct {
@@ -1023,3 +1041,154 @@ func TestVariousBindingModes(t *testing.T) {
1023
1041
}
1024
1042
})
1025
1043
}
1044
+
1045
+ func TestLOBRetrievalWithArrow (t * testing.T ) {
1046
+ testLOBRetrieval (t , true )
1047
+ }
1048
+
1049
+ func TestLOBRetrievalWithJSON (t * testing.T ) {
1050
+ testLOBRetrieval (t , false )
1051
+ }
1052
+
1053
+ func testLOBRetrieval (t * testing.T , useArrowFormat bool ) {
1054
+ // the LOB sizes to be tested
1055
+ testSizes := [5 ]int {smallSize , originSize , mediumSize , largeSize , maxLOBSize }
1056
+ var res string
1057
+
1058
+ runDBTest (t , func (dbt * DBTest ) {
1059
+ dbt .exec (enableFeatureMaxLOBSize )
1060
+ if useArrowFormat {
1061
+ dbt .mustExec (forceARROW )
1062
+ } else {
1063
+ dbt .mustExec (forceJSON )
1064
+ }
1065
+
1066
+ for _ , testSize := range testSizes {
1067
+ t .Run (fmt .Sprintf ("testLOB_%v_useArrowFormat=%v" , strconv .Itoa (testSize ), strconv .FormatBool (useArrowFormat )), func (t * testing.T ) {
1068
+ rows , err := dbt .query (fmt .Sprintf ("SELECT randstr(%v, 124)" , testSize ))
1069
+ assertNilF (t , err )
1070
+ defer rows .Close ()
1071
+ assertTrueF (t , rows .Next (), fmt .Sprintf ("no rows returned for the LOB size %v" , testSize ))
1072
+
1073
+ // retrieve the result
1074
+ err = rows .Scan (& res )
1075
+ assertNilF (t , err )
1076
+
1077
+ // verify the length of the result
1078
+ assertEqualF (t , len (res ), testSize )
1079
+ })
1080
+ }
1081
+ dbt .exec (unsetFeatureMaxLOBSize )
1082
+ })
1083
+ }
1084
+
1085
+ func TestInsertLobDataWithLiteralArrow (t * testing.T ) {
1086
+ testInsertLOBData (t , true , true )
1087
+ }
1088
+
1089
+ func TestInsertLobDataWithLiteralJSON (t * testing.T ) {
1090
+ testInsertLOBData (t , false , true )
1091
+ }
1092
+
1093
+ func TestInsertLobDataWithBindingsArrow (t * testing.T ) {
1094
+ testInsertLOBData (t , true , false )
1095
+ }
1096
+
1097
+ func TestInsertLobDataWithBindingsJSON (t * testing.T ) {
1098
+ testInsertLOBData (t , false , false )
1099
+ }
1100
+
1101
+ func testInsertLOBData (t * testing.T , useArrowFormat bool , isLiteral bool ) {
1102
+ expectedNumCols := 3
1103
+ columnMeta := []struct {
1104
+ columnName string
1105
+ columnType reflect.Type
1106
+ }{
1107
+ {"C1" , reflect .TypeOf ("" )},
1108
+ {"C2" , reflect .TypeOf ("" )},
1109
+ {"C3" , reflect .TypeOf (int64 (0 ))},
1110
+ }
1111
+ testCases := []struct {
1112
+ testDesc string
1113
+ c1Size int
1114
+ c2Size int
1115
+ c3Size int
1116
+ }{
1117
+ {"testLOBInsertSmallSize" , smallSize , smallSize , lobRandomRange },
1118
+ {"testLOBInsertOriginSize" , originSize , originSize , lobRandomRange },
1119
+ {"testLOBInsertMediumSize" , mediumSize , originSize , lobRandomRange },
1120
+ {"testLOBInsertLargeSize" , largeSize , originSize , lobRandomRange },
1121
+ {"testLOBInsertMaxSize" , maxLOBSize , originSize , lobRandomRange },
1122
+ }
1123
+
1124
+ runDBTest (t , func (dbt * DBTest ) {
1125
+ var c1 string
1126
+ var c2 string
1127
+ var c3 int
1128
+
1129
+ dbt .exec (enableFeatureMaxLOBSize )
1130
+ if useArrowFormat {
1131
+ dbt .mustExec (forceARROW )
1132
+ } else {
1133
+ dbt .mustExec (forceJSON )
1134
+ }
1135
+
1136
+ for _ , tc := range testCases {
1137
+ t .Run (tc .testDesc , func (t * testing.T ) {
1138
+ // initialize test data
1139
+ c1Data := randomString (tc .c1Size )
1140
+ c2Data := randomString (tc .c2Size )
1141
+ c3Data := rand .Intn (tc .c3Size )
1142
+
1143
+ dbt .mustExec (fmt .Sprintf ("CREATE OR REPLACE TABLE lob_test_table (c1 varchar(%v), c2 varchar(%v), c3 int)" , tc .c1Size , tc .c2Size ))
1144
+ if isLiteral {
1145
+ dbt .mustExec (fmt .Sprintf ("INSERT INTO lob_test_table VALUES ('%s', '%s', %v)" , c1Data , c2Data , c3Data ))
1146
+ } else {
1147
+ dbt .mustExec ("INSERT INTO lob_test_table VALUES (?, ?, ?)" , c1Data , c2Data , c3Data )
1148
+ }
1149
+ rows , err := dbt .query ("SELECT * FROM lob_test_table" )
1150
+ assertNilF (t , err )
1151
+ defer rows .Close ()
1152
+ assertTrueF (t , rows .Next (), fmt .Sprintf ("%s: no rows returned" , tc .testDesc ))
1153
+
1154
+ err = rows .Scan (& c1 , & c2 , & c3 )
1155
+ assertNilF (t , err )
1156
+
1157
+ // check the number of columns
1158
+ columnTypes , err := rows .ColumnTypes ()
1159
+ assertNilF (t , err )
1160
+ assertEqualF (t , len (columnTypes ), expectedNumCols )
1161
+
1162
+ // verify the column metadata: name, type and length
1163
+ for colIdx := 0 ; colIdx < expectedNumCols ; colIdx ++ {
1164
+ colName := columnTypes [colIdx ].Name ()
1165
+ assertEqualF (t , colName , columnMeta [colIdx ].columnName )
1166
+
1167
+ colType := columnTypes [colIdx ].ScanType ()
1168
+ assertEqualF (t , colType , columnMeta [colIdx ].columnType )
1169
+
1170
+ colLength , ok := columnTypes [colIdx ].Length ()
1171
+
1172
+ switch colIdx {
1173
+ case 0 :
1174
+ assertTrueF (t , ok )
1175
+ assertEqualF (t , colLength , int64 (tc .c1Size ))
1176
+ // verify the data
1177
+ assertEqualF (t , c1 , c1Data )
1178
+ case 1 :
1179
+ assertTrueF (t , ok )
1180
+ assertEqualF (t , colLength , int64 (tc .c2Size ))
1181
+ // verify the data
1182
+ assertEqualF (t , c2 , c2Data )
1183
+ case 2 :
1184
+ assertFalseF (t , ok )
1185
+ // verify the data
1186
+ assertEqualF (t , c3 , c3Data )
1187
+ }
1188
+ }
1189
+ })
1190
+ dbt .mustExec ("DROP TABLE IF EXISTS lob_test_table" )
1191
+ }
1192
+ dbt .exec (unsetFeatureMaxLOBSize )
1193
+ })
1194
+ }
0 commit comments