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
92 changes: 72 additions & 20 deletions src/json_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
* @author Joshua C. Randall <jcrandall@alum.mit.edu>
*/

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include <jansson.h>

Expand Down Expand Up @@ -103,6 +105,26 @@ static const char* map_access_level(const char *access_level, baton_error_t *err
return NULL;
}

static void set_query_prepare_error(const char *context, baton_error_t *error) {
const int errnum = errno;

init_baton_error(error);

if (errnum == EOVERFLOW) {
set_baton_error(error, CAT_INVALID_ARGUMENT,
"Query exceeded the maximum of %d conditions while "
"preparing %s constraints", MAX_NUM_CONDITIONS, context);
}
else if (errnum != 0) {
set_baton_error(error, errnum,
"Failed to prepare %s constraints: error %d %s", context, errnum,
strerror(errnum));
}
else {
set_baton_error(error, -1, "Failed to prepare %s constraints", context);
}
}

// Map an iCAT token back to a user-visible access level.
static const char* revmap_access_level(const char *icat_level) {
if (str_equals_ignore_case(icat_level, ACCESS_NULL, MAX_STR_LEN)) {
Expand Down Expand Up @@ -208,8 +230,8 @@ const char* ensure_valid_operator(const char *op, baton_error_t *error) {
};
init_baton_error(error);

size_t valid_index;
int valid = 0;
size_t valid_index = 0;
int valid = 0;
for (size_t i = 0; i < num_operators; i++) {
if (str_equals_ignore_case(op, operators[i], MAX_STR_LEN)) {
valid = 1;
Expand Down Expand Up @@ -258,6 +280,10 @@ json_t* do_search(rcComm_t *conn,
}

query_in = make_query_input(SEARCH_MAX_ROWS, format->num_columns, format->columns);
if (!query_in) {
set_query_prepare_error("query", error);
goto error;
}

if (root_path) {
rodsPath_t rods_path;
Expand All @@ -278,6 +304,10 @@ json_t* do_search(rcComm_t *conn,
else {
logmsg(DEBUG, "Limiting search to path '%s'", root_path);
query_in = prepare_path_search(query_in, root_path);
if (!query_in) {
set_query_prepare_error("path", error);
goto error;
}
}
}
}
Expand All @@ -287,11 +317,15 @@ json_t* do_search(rcComm_t *conn,
if (error->code != 0) goto error;

query_in = prepare_json_avu_search(query_in, avus, prepare_avu, error);
if (error->code != 0) goto error;
if (error->code != 0 || !query_in) goto error;

// Report good replicates only
if (format->good_repl) {
query_in = limit_to_good_repl(query_in);
if (!query_in) {
set_query_prepare_error("replica", error);
goto error;
}
}

// ACL is optional
Expand All @@ -300,7 +334,7 @@ json_t* do_search(rcComm_t *conn,
if (error->code != 0) goto error;

query_in = prepare_json_acl_search(query_in, acl, prepare_acl, error);
if (error->code != 0) goto error;
if (error->code != 0 || !query_in) goto error;
}

// Timestamp is optional
Expand All @@ -310,7 +344,7 @@ json_t* do_search(rcComm_t *conn,

query_in = prepare_json_tps_search(query_in, tps, prepare_cre,
prepare_mod, error);
if (error->code != 0) goto error;
if (error->code != 0 || !query_in) goto error;
}

if (zone_hint) {
Expand Down Expand Up @@ -355,7 +389,7 @@ json_t* do_specific(rcComm_t *conn,
if (error->code != 0) goto error;

format = prepare_json_specific_labels(conn, specific, prepare_labels, error);
if (error->code != 0) goto error;
if (error->code != 0 || !format) goto error;

if (zone_name) {
logmsg(TRACE, "Setting zone to '%s'", zone_name);
Expand Down Expand Up @@ -509,6 +543,14 @@ json_t* do_squery(rcComm_t *conn,
if (status == 0) {
logmsg(DEBUG, "Successfully fetched chunk %d of query", chunk_num);

const size_t num_attr = query_out->attriCnt;
if (num_attr > MAX_NUM_COLUMNS) {
set_baton_error(error, CAT_INVALID_ARGUMENT,
"Specific query result exceeded maximum of %d columns "
"(got %lu)", MAX_NUM_COLUMNS, num_attr);
goto error;
}

// Allows query_out to be freed
continue_flag = query_out->continueInx;

Expand Down Expand Up @@ -681,6 +723,10 @@ genQueryInp_t* prepare_json_acl_search(genQueryInp_t *query_in,
if (error->code != 0) goto error;

query_in = prepare(query_in, owner_name, access_level);
if (!query_in) {
set_query_prepare_error("ACL", error);
goto error;
}
}

return query_in;
Expand All @@ -693,8 +739,6 @@ genQueryInp_t* prepare_json_avu_search(genQueryInp_t *query_in,
const json_t *avus,
const prepare_avu_search_cb prepare,
baton_error_t *error) {
json_t *in_opvalue = NULL;

init_baton_error(error);

const size_t num_clauses = json_array_size(avus);
Expand Down Expand Up @@ -735,18 +779,16 @@ genQueryInp_t* prepare_json_avu_search(genQueryInp_t *query_in,
logmsg(DEBUG, "Preparing AVU search a: '%s' v: '%s', op: '%s'", attr_name,
attr_value, valid_oper);

prepare(query_in, attr_name, attr_value, valid_oper);

if (in_opvalue) {
json_decref(in_opvalue);
in_opvalue = NULL; // Reset for any subsequent IN clause
query_in = prepare(query_in, attr_name, attr_value, valid_oper);
if (!query_in) {
set_query_prepare_error("AVU", error);
goto error;
}
}

return query_in;

error:
if (in_opvalue) json_decref(in_opvalue);
return query_in;
}

Expand All @@ -765,7 +807,12 @@ specificQueryInp_t* prepare_json_specific_query(specificQueryInp_t *squery_in,

logmsg(DEBUG, "Preparing specific search s: '%s'", sql);

prepare(squery_in, sql, args);
specificQueryInp_t *prepared = prepare(squery_in, sql, args);
if (!prepared) {
set_query_prepare_error("specific query", error);
goto error;
}
squery_in = prepared;

if (args) {
json_decref(args);
Expand All @@ -791,6 +838,10 @@ query_format_in_t* prepare_json_specific_labels(rcComm_t *conn,
logmsg(DEBUG, "Preparing labels for specific search: '%s'", sql);

format = prepare(conn, sql);
if (!format) {
set_query_prepare_error("specific query labels", error);
goto error;
}

return format;

Expand Down Expand Up @@ -853,7 +904,12 @@ genQueryInp_t* prepare_json_tps_search(genQueryInp_t *query_in,
goto error;
}

prepare(query_in, raw_timestamp, oper);
query_in = prepare(query_in, raw_timestamp, oper);
if (!query_in) {
free(raw_timestamp);
set_query_prepare_error("timestamp", error);
goto error;
}
free(raw_timestamp);
}

Expand Down Expand Up @@ -1197,8 +1253,6 @@ json_t* add_acl_json_array(rcComm_t *conn, json_t *array, baton_error_t *error)
}

json_t* map_access_args(json_t *query, baton_error_t *error) {
json_t *user_info = NULL;

init_baton_error(error);

if (has_acl(query)) {
Expand Down Expand Up @@ -1233,8 +1287,6 @@ json_t* map_access_args(json_t *query, baton_error_t *error) {
return query;

error:
if (user_info) json_decref(user_info);

return NULL;
}

Expand Down
Loading