@@ -867,7 +867,7 @@ local function process_tuple(self, state, tuple, opts)
867
867
if clock .monotonic64 () > qcontext .deadline_clock then
868
868
error (e .timeout_exceeded ((
869
869
' query execution timeout exceeded timeout_ms limit (%s ms)' ):format (
870
- tostring (self . settings .timeout_ms ))))
870
+ tostring (state . qcontext . query_settings .timeout_ms ))))
871
871
end
872
872
local collection_name = opts .collection_name
873
873
local pcre = opts .pcre
@@ -1038,21 +1038,23 @@ local function select_internal(self, collection_name, from, filter, args, extra)
1038
1038
collection_name ))
1039
1039
1040
1040
-- read-write variables for process_tuple
1041
+ local qcontext = extra .qcontext
1041
1042
local select_state = {
1042
1043
count = 0 ,
1043
1044
objs = {},
1044
1045
pivot_found = false ,
1045
- qcontext = extra . qcontext
1046
+ qcontext = qcontext
1046
1047
}
1047
1048
1048
1049
-- read only process_tuple options
1050
+ local query_settings = qcontext .query_settings
1049
1051
local select_opts = {
1050
1052
limit = args .limit ,
1051
1053
filter = filter ,
1052
1054
do_filter = not full_match ,
1053
1055
pivot_filter = nil , -- filled later if needed
1054
- resulting_object_cnt_max = self . settings .resulting_object_cnt_max ,
1055
- fetched_object_cnt_max = self . settings .fetched_object_cnt_max ,
1056
+ resulting_object_cnt_max = query_settings .resulting_object_cnt_max ,
1057
+ fetched_object_cnt_max = query_settings .fetched_object_cnt_max ,
1056
1058
collection_name = collection_name ,
1057
1059
unflatten_tuple = self .funcs .unflatten_tuple ,
1058
1060
use_tomap = self .collection_use_tomap [collection_name ] or false ,
@@ -1079,10 +1081,10 @@ local function select_internal(self, collection_name, from, filter, args, extra)
1079
1081
collection_name )
1080
1082
1081
1083
-- count full scan select request
1082
- extra . qcontext .statistics .select_requests_cnt =
1083
- extra . qcontext .statistics .select_requests_cnt + 1
1084
- extra . qcontext .statistics .full_scan_select_requests_cnt =
1085
- extra . qcontext .statistics .full_scan_select_requests_cnt + 1
1084
+ qcontext .statistics .select_requests_cnt =
1085
+ qcontext .statistics .select_requests_cnt + 1
1086
+ qcontext .statistics .full_scan_select_requests_cnt =
1087
+ qcontext .statistics .full_scan_select_requests_cnt + 1
1086
1088
1087
1089
for _ , tuple in primary_index :pairs () do
1088
1090
assert (pivot == nil ,
@@ -1127,10 +1129,10 @@ local function select_internal(self, collection_name, from, filter, args, extra)
1127
1129
local tuple_count = 0
1128
1130
1129
1131
-- count index select request
1130
- extra . qcontext .statistics .select_requests_cnt =
1131
- extra . qcontext .statistics .select_requests_cnt + 1
1132
- extra . qcontext .statistics .index_select_requests_cnt =
1133
- extra . qcontext .statistics .index_select_requests_cnt + 1
1132
+ qcontext .statistics .select_requests_cnt =
1133
+ qcontext .statistics .select_requests_cnt + 1
1134
+ qcontext .statistics .index_select_requests_cnt =
1135
+ qcontext .statistics .index_select_requests_cnt + 1
1134
1136
1135
1137
for _ , tuple in index :pairs (index_value , iterator_opts ) do
1136
1138
tuple_count = tuple_count + 1
@@ -1307,23 +1309,58 @@ local function validate_funcs(funcs)
1307
1309
type (funcs .delete_tuple ))
1308
1310
end
1309
1311
1312
+ local function validate_query_settings (query_settings , opts )
1313
+ local opts = opts or {}
1314
+ local allow_nil = opts .allow_nil or false
1315
+
1316
+ local resulting_object_cnt_max = query_settings .resulting_object_cnt_max
1317
+ local fetched_object_cnt_max = query_settings .fetched_object_cnt_max
1318
+ local timeout_ms = query_settings .timeout_ms
1319
+
1320
+ if not allow_nil or type (resulting_object_cnt_max ) ~= ' nil' then
1321
+ assert (type (resulting_object_cnt_max ) == ' number' and
1322
+ resulting_object_cnt_max > 0 ,
1323
+ ' resulting_object_cnt_max must be natural number' )
1324
+ end
1325
+ if not allow_nil or type (fetched_object_cnt_max ) ~= ' nil' then
1326
+ assert (type (fetched_object_cnt_max ) == ' number' and
1327
+ fetched_object_cnt_max > 0 ,
1328
+ ' fetched_object_cnt_max must be natural number' )
1329
+ end
1330
+ if not allow_nil or type (timeout_ms ) ~= ' nil' then
1331
+ assert (type (timeout_ms ) == ' number' or (type (timeout_ms ) == ' cdata' and
1332
+ tostring (ffi .typeof (timeout_ms )) == ' ctype<uint64_t>' ),
1333
+ ' timeout_ms must a number, got ' .. type (timeout_ms ))
1334
+ assert (timeout_ms <= TIMEOUT_INFINITY ,
1335
+ (' timeouts more then graphql.TIMEOUT_INFINITY (%s) ' ..
1336
+ ' do not supported' ):format (tostring (TIMEOUT_INFINITY )))
1337
+ end
1338
+ end
1339
+
1310
1340
--- This function is called on first select related to a query. Its purpose is
1311
1341
--- to initialize qcontext table.
1312
1342
--- @tparam table accessor
1313
1343
--- @tparam table qcontext per-query table which stores query internal state;
1314
1344
--- all neccessary initialization of this parameter should be performed by this
1315
1345
-- function
1316
1346
local function init_qcontext (accessor , qcontext )
1317
- local settings = accessor .settings
1347
+ for k , v in pairs (accessor .query_settings_default ) do
1348
+ if qcontext .query_settings [k ] == nil then
1349
+ qcontext .query_settings [k ] = v
1350
+ end
1351
+ end
1352
+ validate_query_settings (qcontext .query_settings )
1353
+
1354
+ qcontext .deadline_clock = clock .monotonic64 () +
1355
+ qcontext .query_settings .timeout_ms * 1000 * 1000
1356
+
1318
1357
qcontext .statistics = {
1319
1358
resulting_object_cnt = 0 ,
1320
1359
fetched_object_cnt = 0 ,
1321
1360
select_requests_cnt = 0 ,
1322
1361
full_scan_select_requests_cnt = 0 ,
1323
1362
index_select_requests_cnt = 0 ,
1324
1363
}
1325
- qcontext .deadline_clock = clock .monotonic64 () +
1326
- settings .timeout_ms * 1000 * 1000
1327
1364
end
1328
1365
1329
1366
--- Create default unflatten/flatten/xflatten functions, that can be called
@@ -1474,12 +1511,24 @@ function accessor_general.new(opts, funcs)
1474
1511
local collections = opts .collections
1475
1512
local service_fields = opts .service_fields
1476
1513
local indexes = opts .indexes
1514
+
1515
+ check (schemas , ' schemas' , ' table' )
1516
+ check (collections , ' collections' , ' table' )
1517
+ check (service_fields , ' service_fields' , ' table' )
1518
+ check (indexes , ' indexes' , ' table' )
1519
+
1477
1520
local resulting_object_cnt_max = opts .resulting_object_cnt_max or
1478
- DEF_RESULTING_OBJECT_CNT_MAX
1521
+ DEF_RESULTING_OBJECT_CNT_MAX
1479
1522
local fetched_object_cnt_max = opts .fetched_object_cnt_max or
1480
- DEF_FETCHED_OBJECT_CNT_MAX
1481
- -- TODO: move this setting to `tgql.compile` after #59
1523
+ DEF_FETCHED_OBJECT_CNT_MAX
1482
1524
local timeout_ms = opts .timeout_ms or DEF_TIMEOUT_MS
1525
+ local query_settings_default = {
1526
+ resulting_object_cnt_max = resulting_object_cnt_max ,
1527
+ fetched_object_cnt_max = fetched_object_cnt_max ,
1528
+ timeout_ms = timeout_ms ,
1529
+ }
1530
+ validate_query_settings (query_settings_default )
1531
+
1483
1532
-- Mutations are disabled for avro-schema-2*, because it can work
1484
1533
-- incorrectly for schemas with nullable types.
1485
1534
local enable_mutations
@@ -1488,27 +1537,6 @@ function accessor_general.new(opts, funcs)
1488
1537
else
1489
1538
enable_mutations = opts .enable_mutations
1490
1539
end
1491
-
1492
- assert (type (schemas ) == ' table' ,
1493
- ' schemas must be a table, got ' .. type (schemas ))
1494
- assert (type (collections ) == ' table' ,
1495
- ' collections must be a table, got ' .. type (collections ))
1496
- assert (type (service_fields ) == ' table' ,
1497
- ' service_fields must be a table, got ' .. type (service_fields ))
1498
- assert (type (indexes ) == ' table' ,
1499
- ' indexes must be a table, got ' .. type (indexes ))
1500
- assert (type (resulting_object_cnt_max ) == ' number' and
1501
- resulting_object_cnt_max > 0 ,
1502
- ' resulting_object_cnt_max must be natural number' )
1503
- assert (type (fetched_object_cnt_max ) == ' number' and
1504
- fetched_object_cnt_max > 0 ,
1505
- ' fetched_object_cnt_max must be natural number' )
1506
- assert (type (timeout_ms ) == ' number' or (type (timeout_ms ) == ' cdata' and
1507
- tostring (ffi .typeof (timeout_ms )) == ' ctype<uint64_t>' ),
1508
- ' timeout_ms must a number, got ' .. type (timeout_ms ))
1509
- assert (timeout_ms <= TIMEOUT_INFINITY ,
1510
- (' timeouts more then graphql.TIMEOUT_INFINITY (%s) ' ..
1511
- ' do not supported' ):format (tostring (TIMEOUT_INFINITY )))
1512
1540
check (enable_mutations , ' enable_mutations' , ' boolean' )
1513
1541
1514
1542
local models , service_fields_defaults = compile_schemas (schemas ,
@@ -1537,11 +1565,9 @@ function accessor_general.new(opts, funcs)
1537
1565
index_cache = index_cache ,
1538
1566
funcs = funcs ,
1539
1567
settings = {
1540
- resulting_object_cnt_max = resulting_object_cnt_max ,
1541
- fetched_object_cnt_max = fetched_object_cnt_max ,
1542
- timeout_ms = timeout_ms ,
1543
1568
enable_mutations = enable_mutations ,
1544
- }
1569
+ },
1570
+ query_settings_default = query_settings_default ,
1545
1571
}, {
1546
1572
__index = {
1547
1573
select = function (self , parent , collection_name , from ,
@@ -1576,4 +1602,7 @@ function accessor_general.new(opts, funcs)
1576
1602
})
1577
1603
end
1578
1604
1605
+ -- export the function
1606
+ accessor_general .validate_query_settings = validate_query_settings
1607
+
1579
1608
return accessor_general
0 commit comments