mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 21:23:03 +01:00
Style.
This commit is contained in:
parent
a75add80c4
commit
8dca837420
490
src/dsql/ddl.cpp
490
src/dsql/ddl.cpp
File diff suppressed because it is too large
Load Diff
@ -88,13 +88,12 @@ static SSHORT filter_sub_type(dsql_req*, const dsql_nod*);
|
||||
static bool get_indices(SSHORT*, const SCHAR**, SSHORT*, SCHAR**);
|
||||
static USHORT get_plan_info(thread_db*, dsql_req*, SSHORT, SCHAR**);
|
||||
static USHORT get_request_info(thread_db*, dsql_req*, SSHORT, UCHAR*);
|
||||
static bool get_rsb_item(SSHORT*, const SCHAR**, SSHORT*, SCHAR**, USHORT*,
|
||||
USHORT*);
|
||||
static bool get_rsb_item(SSHORT*, const SCHAR**, SSHORT*, SCHAR**, USHORT*, USHORT*);
|
||||
static dsql_dbb* init(Attachment*);
|
||||
static void map_in_out(dsql_req*, dsql_msg*, USHORT, const UCHAR*, USHORT, UCHAR*, const UCHAR* = 0);
|
||||
static USHORT parse_blr(USHORT, const UCHAR*, const USHORT, dsql_par*);
|
||||
static dsql_req* prepare(thread_db*, dsql_dbb*, jrd_tra*, USHORT, const TEXT*, USHORT, USHORT);
|
||||
static UCHAR* put_item(UCHAR, USHORT, const UCHAR*, UCHAR*, const UCHAR* const);
|
||||
static UCHAR* put_item(UCHAR, const USHORT, const UCHAR*, UCHAR*, const UCHAR* const);
|
||||
static void release_request(thread_db*, dsql_req*, bool);
|
||||
static void sql_info(thread_db*, dsql_req*, USHORT, const UCHAR*, USHORT, UCHAR*);
|
||||
static UCHAR* var_info(dsql_msg*, const UCHAR*, const UCHAR* const, UCHAR*,
|
||||
@ -106,7 +105,8 @@ unsigned DSQL_debug = 0;
|
||||
|
||||
namespace
|
||||
{
|
||||
const SCHAR db_hdr_info_items[] = {
|
||||
const SCHAR db_hdr_info_items[] =
|
||||
{
|
||||
isc_info_db_sql_dialect,
|
||||
isc_info_ods_version,
|
||||
isc_info_ods_minor_version,
|
||||
@ -115,16 +115,19 @@ namespace
|
||||
isc_info_end
|
||||
};
|
||||
|
||||
const SCHAR explain_info[] = {
|
||||
const SCHAR explain_info[] =
|
||||
{
|
||||
isc_info_access_path
|
||||
};
|
||||
|
||||
const SCHAR record_info[] = {
|
||||
const SCHAR record_info[] =
|
||||
{
|
||||
isc_info_req_update_count, isc_info_req_delete_count,
|
||||
isc_info_req_select_count, isc_info_req_insert_count
|
||||
};
|
||||
|
||||
const UCHAR sql_records_info[] = {
|
||||
const UCHAR sql_records_info[] =
|
||||
{
|
||||
isc_info_sql_records
|
||||
};
|
||||
|
||||
@ -152,8 +155,7 @@ dsql_dbb::~dsql_dbb()
|
||||
@param attachment
|
||||
|
||||
**/
|
||||
dsql_req* DSQL_allocate_statement(thread_db* tdbb,
|
||||
Attachment* attachment)
|
||||
dsql_req* DSQL_allocate_statement(thread_db* tdbb, Attachment* attachment)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
@ -225,14 +227,15 @@ void DSQL_execute(thread_db* tdbb,
|
||||
/* If the request is a SELECT or blob statement then this is an open.
|
||||
Make sure the cursor is not already open. */
|
||||
|
||||
if (request->req_type == REQ_SELECT ||
|
||||
request->req_type == REQ_EXEC_BLOCK ||
|
||||
request->req_type == REQ_SELECT_BLOCK ||
|
||||
request->req_type == REQ_SELECT_UPD ||
|
||||
request->req_type == REQ_EMBED_SELECT ||
|
||||
request->req_type == REQ_GET_SEGMENT ||
|
||||
request->req_type == REQ_PUT_SEGMENT)
|
||||
switch (request->req_type)
|
||||
{
|
||||
case REQ_SELECT:
|
||||
case REQ_EXEC_BLOCK:
|
||||
case REQ_SELECT_BLOCK:
|
||||
case REQ_SELECT_UPD:
|
||||
case REQ_EMBED_SELECT:
|
||||
case REQ_GET_SEGMENT:
|
||||
case REQ_PUT_SEGMENT:
|
||||
if (request->req_flags & REQ_cursor_open)
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
|
||||
@ -252,10 +255,8 @@ void DSQL_execute(thread_db* tdbb,
|
||||
if (request->req_type != REQ_EMBED_SELECT)
|
||||
{
|
||||
execute_request(tdbb, request, tra_handle,
|
||||
in_blr_length, in_blr,
|
||||
in_msg_length, in_msg,
|
||||
out_blr_length, out_blr,
|
||||
out_msg_length, out_msg,
|
||||
in_blr_length, in_blr, in_msg_length, in_msg,
|
||||
out_blr_length, out_blr, out_msg_length, out_msg,
|
||||
singleton);
|
||||
}
|
||||
else
|
||||
@ -269,13 +270,16 @@ void DSQL_execute(thread_db* tdbb,
|
||||
* a singleton SELECT. In that event, we don't add the cursor
|
||||
* to the list of open cursors (it's not really open).
|
||||
*/
|
||||
if ((request->req_type == REQ_SELECT && out_msg_length == 0) ||
|
||||
(request->req_type == REQ_SELECT_BLOCK) ||
|
||||
request->req_type == REQ_SELECT_UPD ||
|
||||
request->req_type == REQ_EMBED_SELECT ||
|
||||
request->req_type == REQ_GET_SEGMENT ||
|
||||
request->req_type == REQ_PUT_SEGMENT)
|
||||
switch (request->req_type)
|
||||
{
|
||||
case REQ_SELECT:
|
||||
if (out_msg_length != 0)
|
||||
break;
|
||||
case REQ_SELECT_BLOCK:
|
||||
case REQ_SELECT_UPD:
|
||||
case REQ_EMBED_SELECT:
|
||||
case REQ_GET_SEGMENT:
|
||||
case REQ_PUT_SEGMENT:
|
||||
request->req_flags |= REQ_cursor_open;
|
||||
TRA_link_cursor(request->req_transaction, request);
|
||||
}
|
||||
@ -317,14 +321,9 @@ void DSQL_execute_immediate(thread_db* tdbb,
|
||||
USHORT out_msg_type, USHORT out_msg_length, UCHAR* out_msg)
|
||||
{
|
||||
execute_immediate(tdbb, attachment, tra_handle, length,
|
||||
string, dialect, in_blr_length,
|
||||
in_blr,
|
||||
in_msg_type, in_msg_length,
|
||||
in_msg,
|
||||
out_blr_length,
|
||||
out_blr,
|
||||
out_msg_type, out_msg_length,
|
||||
out_msg);
|
||||
string, dialect,
|
||||
in_blr_length, in_blr, in_msg_type, in_msg_length, in_msg,
|
||||
out_blr_length, out_blr, out_msg_type, out_msg_length, out_msg);
|
||||
}
|
||||
|
||||
|
||||
@ -374,8 +373,7 @@ ISC_STATUS DSQL_fetch(thread_db* tdbb,
|
||||
in the same direction as before, so optimize out messages of that
|
||||
type */
|
||||
|
||||
if (request->req_type == REQ_SELECT &&
|
||||
request->req_dbb->dbb_base_level >= 5)
|
||||
if (request->req_type == REQ_SELECT && request->req_dbb->dbb_base_level >= 5)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
@ -484,8 +482,7 @@ ISC_STATUS DSQL_fetch(thread_db* tdbb,
|
||||
|
||||
dsql_par* parameter = request->req_blob->blb_segment;
|
||||
dsql_par* null = parameter->par_null;
|
||||
USHORT* ret_length =
|
||||
(USHORT *) (dsql_msg_buf + (IPTR) null->par_user_desc.dsc_address);
|
||||
USHORT* ret_length = (USHORT *) (dsql_msg_buf + (IPTR) null->par_user_desc.dsc_address);
|
||||
UCHAR* buffer = dsql_msg_buf + (IPTR) parameter->par_user_desc.dsc_address;
|
||||
|
||||
*ret_length = BLB_get_segment(tdbb, request->req_blob->blb_blob,
|
||||
@ -529,9 +526,7 @@ ISC_STATUS DSQL_fetch(thread_db* tdbb,
|
||||
@param option
|
||||
|
||||
**/
|
||||
void DSQL_free_statement(thread_db* tdbb,
|
||||
dsql_req* request,
|
||||
USHORT option)
|
||||
void DSQL_free_statement(thread_db* tdbb, dsql_req* request, USHORT option)
|
||||
{
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
@ -790,8 +785,7 @@ void DSQL_set_cursor(thread_db* tdbb,
|
||||
// Note that "" will be replaced with ".
|
||||
// The code is very strange, because it doesn't check for "" really
|
||||
// and thus deletes one isolated " in the middle of the cursor.
|
||||
for (Firebird::string::iterator i = cursor.begin();
|
||||
i < cursor.end(); ++i)
|
||||
for (Firebird::string::iterator i = cursor.begin(); i < cursor.end(); ++i)
|
||||
{
|
||||
if (*i == '\"') {
|
||||
cursor.erase(i);
|
||||
@ -800,7 +794,7 @@ void DSQL_set_cursor(thread_db* tdbb,
|
||||
}
|
||||
else // not quoted name
|
||||
{
|
||||
Firebird::string::size_type i = cursor.find(' ');
|
||||
const Firebird::string::size_type i = cursor.find(' ');
|
||||
if (i != Firebird::string::npos)
|
||||
{
|
||||
cursor.resize(i);
|
||||
@ -821,8 +815,7 @@ void DSQL_set_cursor(thread_db* tdbb,
|
||||
|
||||
// If there already is a different cursor by the same name, bitch
|
||||
|
||||
const dsql_sym* symbol =
|
||||
HSHD_lookup(request->req_dbb, cursor.c_str(), length, SYM_cursor, 0);
|
||||
const dsql_sym* symbol = HSHD_lookup(request->req_dbb, cursor.c_str(), length, SYM_cursor, 0);
|
||||
if (symbol)
|
||||
{
|
||||
if (request->req_cursor == symbol)
|
||||
@ -837,8 +830,7 @@ void DSQL_set_cursor(thread_db* tdbb,
|
||||
// We already know there is no cursor by this name in the hash table
|
||||
|
||||
if (!request->req_cursor) {
|
||||
request->req_cursor = MAKE_symbol(request->req_dbb, cursor.c_str(),
|
||||
length, SYM_cursor, request);
|
||||
request->req_cursor = MAKE_symbol(request->req_dbb, cursor.c_str(), length, SYM_cursor, request);
|
||||
}
|
||||
else {
|
||||
fb_assert(request->req_cursor != symbol);
|
||||
@ -897,8 +889,7 @@ static void close_cursor(thread_db* tdbb, dsql_req* request)
|
||||
ThreadStatusGuard status_vector(tdbb);
|
||||
try
|
||||
{
|
||||
if (request->req_type == REQ_GET_SEGMENT ||
|
||||
request->req_type == REQ_PUT_SEGMENT)
|
||||
if (request->req_type == REQ_GET_SEGMENT || request->req_type == REQ_PUT_SEGMENT)
|
||||
{
|
||||
BLB_close(tdbb, request->req_blob->blb_blob);
|
||||
request->req_blob->blb_blob = NULL;
|
||||
@ -988,9 +979,7 @@ static void execute_blob(thread_db* tdbb,
|
||||
UCHAR bpb[24];
|
||||
|
||||
dsql_blb* blob = request->req_blob;
|
||||
map_in_out(request, blob->blb_open_in_msg,
|
||||
in_blr_length, in_blr,
|
||||
in_msg_length, NULL, in_msg);
|
||||
map_in_out(request, blob->blb_open_in_msg, in_blr_length, in_blr, in_msg_length, NULL, in_msg);
|
||||
|
||||
UCHAR* p = bpb;
|
||||
*p++ = isc_bpb_version1;
|
||||
@ -1023,8 +1012,8 @@ static void execute_blob(thread_db* tdbb,
|
||||
memset(blob_id, 0, sizeof(bid));
|
||||
}
|
||||
|
||||
request->req_blob->blb_blob = BLB_open2(tdbb, request->req_transaction, blob_id,
|
||||
bpb_length, bpb, true);
|
||||
request->req_blob->blb_blob =
|
||||
BLB_open2(tdbb, request->req_transaction, blob_id, bpb_length, bpb, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1032,12 +1021,10 @@ static void execute_blob(thread_db* tdbb,
|
||||
bid* blob_id = (bid*) parameter->par_desc.dsc_address;
|
||||
memset(blob_id, 0, sizeof(bid));
|
||||
|
||||
request->req_blob->blb_blob = BLB_create2(tdbb, request->req_transaction,
|
||||
blob_id, bpb_length, bpb);
|
||||
request->req_blob->blb_blob =
|
||||
BLB_create2(tdbb, request->req_transaction, blob_id, bpb_length, bpb);
|
||||
|
||||
map_in_out(NULL, blob->blb_open_out_msg,
|
||||
out_blr_length, out_blr,
|
||||
out_msg_length, out_msg);
|
||||
map_in_out(NULL, blob->blb_open_out_msg, out_blr_length, out_blr, out_msg_length, out_msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1131,9 +1118,10 @@ static void execute_immediate(thread_db* tdbb,
|
||||
|
||||
Jrd::ContextPoolHolder context(tdbb, &request->req_pool);
|
||||
|
||||
execute_request(tdbb, request, tra_handle, in_blr_length, in_blr,
|
||||
in_msg_length, in_msg, out_blr_length, out_blr,
|
||||
out_msg_length, out_msg, false);
|
||||
execute_request(tdbb, request, tra_handle,
|
||||
in_blr_length, in_blr, in_msg_length, in_msg,
|
||||
out_blr_length, out_blr, out_msg_length, out_msg,
|
||||
false);
|
||||
|
||||
release_request(tdbb, request, true);
|
||||
}
|
||||
@ -1185,12 +1173,8 @@ static void execute_request(thread_db* tdbb,
|
||||
switch (request->req_type)
|
||||
{
|
||||
case REQ_START_TRANS:
|
||||
JRD_start_transaction(tdbb,
|
||||
&request->req_transaction,
|
||||
1,
|
||||
&request->req_dbb->dbb_attachment,
|
||||
request->req_blr_data.getCount(),
|
||||
request->req_blr_data.begin());
|
||||
JRD_start_transaction(tdbb, &request->req_transaction, 1, &request->req_dbb->dbb_attachment,
|
||||
request->req_blr_data.getCount(), request->req_blr_data.begin());
|
||||
*tra_handle = request->req_transaction;
|
||||
return;
|
||||
|
||||
@ -1256,16 +1240,10 @@ static void execute_request(thread_db* tdbb,
|
||||
JRD_start(tdbb, request->req_request, request->req_transaction, 0);
|
||||
else
|
||||
{
|
||||
map_in_out(request, message,
|
||||
in_blr_length, in_blr,
|
||||
in_msg_length, NULL, in_msg);
|
||||
map_in_out(request, message, in_blr_length, in_blr, in_msg_length, NULL, in_msg);
|
||||
|
||||
JRD_start_and_send(tdbb,
|
||||
request->req_request,
|
||||
request->req_transaction,
|
||||
message->msg_number,
|
||||
message->msg_length,
|
||||
reinterpret_cast<SCHAR*>(message->msg_buffer),
|
||||
JRD_start_and_send(tdbb, request->req_request, request->req_transaction, message->msg_number,
|
||||
message->msg_length, reinterpret_cast<SCHAR*>(message->msg_buffer),
|
||||
0);
|
||||
}
|
||||
|
||||
@ -1284,8 +1262,7 @@ static void execute_request(thread_db* tdbb,
|
||||
whether anything is found by the call to receive. */
|
||||
|
||||
if (out_msg_length && out_blr_length) {
|
||||
parse_blr(out_blr_length, out_blr, out_msg_length,
|
||||
message->msg_parameters);
|
||||
parse_blr(out_blr_length, out_blr, out_msg_length, message->msg_parameters);
|
||||
}
|
||||
else if (!out_msg_length && isBlock) {
|
||||
message = &temp_msg;
|
||||
@ -1311,8 +1288,7 @@ static void execute_request(thread_db* tdbb,
|
||||
second is either another record or the end of record message.
|
||||
In either case, there's more than one record. */
|
||||
|
||||
UCHAR* message_buffer =
|
||||
(UCHAR*)gds__alloc((ULONG) message->msg_length);
|
||||
UCHAR* message_buffer = (UCHAR*) gds__alloc((ULONG) message->msg_length);
|
||||
|
||||
ISC_STATUS status = FB_SUCCESS;
|
||||
|
||||
@ -1362,11 +1338,7 @@ static void execute_request(thread_db* tdbb,
|
||||
UCHAR buffer[20]; // Not used after retrieved
|
||||
if (request->req_type == REQ_UPDATE_CURSOR)
|
||||
{
|
||||
sql_info(tdbb, request,
|
||||
sizeof(sql_records_info),
|
||||
sql_records_info,
|
||||
sizeof(buffer),
|
||||
buffer);
|
||||
sql_info(tdbb, request, sizeof(sql_records_info), sql_records_info, sizeof(buffer), buffer);
|
||||
|
||||
if (!request->req_updates)
|
||||
{
|
||||
@ -1377,11 +1349,7 @@ static void execute_request(thread_db* tdbb,
|
||||
}
|
||||
else if (request->req_type == REQ_DELETE_CURSOR)
|
||||
{
|
||||
sql_info(tdbb, request,
|
||||
sizeof(sql_records_info),
|
||||
sql_records_info,
|
||||
sizeof(buffer),
|
||||
buffer);
|
||||
sql_info(tdbb, request, sizeof(sql_records_info), sql_records_info, sizeof(buffer), buffer);
|
||||
|
||||
if (!request->req_deletes)
|
||||
{
|
||||
@ -1436,10 +1404,8 @@ static SSHORT filter_sub_type( dsql_req* request, const dsql_nod* node)
|
||||
@param plan_ptr
|
||||
|
||||
**/
|
||||
static bool get_indices(
|
||||
SSHORT* explain_length_ptr,
|
||||
const SCHAR** explain_ptr,
|
||||
SSHORT* plan_length_ptr, SCHAR** plan_ptr)
|
||||
static bool get_indices(SSHORT* explain_length_ptr, const SCHAR** explain_ptr,
|
||||
SSHORT* plan_length_ptr, SCHAR** plan_ptr)
|
||||
{
|
||||
USHORT length;
|
||||
|
||||
@ -1452,7 +1418,8 @@ static bool get_indices(
|
||||
extracting the indices used */
|
||||
|
||||
explain_length--;
|
||||
switch (*explain++) {
|
||||
switch (*explain++)
|
||||
{
|
||||
case isc_info_rsb_and:
|
||||
case isc_info_rsb_or:
|
||||
if (!get_indices(&explain_length, &explain, &plan_length, &plan))
|
||||
@ -1577,8 +1544,7 @@ static USHORT get_plan_info(thread_db* tdbb,
|
||||
|
||||
while (explain_length > 0 && buffer_length > 0)
|
||||
{
|
||||
if (!get_rsb_item(&explain_length, &explain, &buffer_length, &plan,
|
||||
&join_count, &level))
|
||||
if (!get_rsb_item(&explain_length, &explain, &buffer_length, &plan, &join_count, &level))
|
||||
{
|
||||
// don't allocate buffer of the same length second time
|
||||
// and let user know plan is incomplete
|
||||
@ -1600,10 +1566,9 @@ static USHORT get_plan_info(thread_db* tdbb,
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
buffer_ptr = temp;
|
||||
buffer_length = (SSHORT) new_length;
|
||||
}
|
||||
|
||||
buffer_ptr = temp;
|
||||
buffer_length = (SSHORT) new_length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1658,11 +1623,11 @@ static USHORT get_request_info(thread_db* tdbb,
|
||||
UCHAR p;
|
||||
while ((p = *data++) != isc_info_end)
|
||||
{
|
||||
const USHORT data_length =
|
||||
static_cast<USHORT>(gds__vax_integer(data, 2));
|
||||
const USHORT data_length = static_cast<USHORT>(gds__vax_integer(data, 2));
|
||||
data += 2;
|
||||
|
||||
switch (p) {
|
||||
switch (p)
|
||||
{
|
||||
case isc_info_req_update_count:
|
||||
request->req_updates = gds__vax_integer(data, data_length);
|
||||
break;
|
||||
@ -1770,7 +1735,7 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
// put out the relation name
|
||||
{ // scope to keep length local.
|
||||
explain_length--;
|
||||
SSHORT length = (UCHAR) * explain++;
|
||||
SSHORT length = (UCHAR) *explain++;
|
||||
explain_length -= length;
|
||||
if ((plan_length -= length) < 0)
|
||||
return false;
|
||||
@ -1799,7 +1764,8 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
|
||||
USHORT union_level = *level_ptr;
|
||||
USHORT union_join_count = 0;
|
||||
while (explain_length > 0 && plan_length > 0) {
|
||||
while (explain_length > 0 && plan_length > 0)
|
||||
{
|
||||
if (!get_rsb_item(&explain_length, &explain, &plan_length, &plan,
|
||||
&union_join_count, &union_level))
|
||||
{
|
||||
@ -1812,10 +1778,12 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
/* for the rest of the members, start the level at 0 so each
|
||||
gets its own "PLAN ... " line */
|
||||
|
||||
while (union_count) {
|
||||
while (union_count)
|
||||
{
|
||||
union_join_count = 0;
|
||||
union_level = 0;
|
||||
while (explain_length > 0 && plan_length > 0) {
|
||||
while (explain_length > 0 && plan_length > 0)
|
||||
{
|
||||
if (!get_rsb_item(&explain_length, &explain, &plan_length,
|
||||
&plan, &union_join_count, &union_level))
|
||||
{
|
||||
@ -1836,7 +1804,8 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
/* if this join is itself part of a join list,
|
||||
but not the first item, then put out a comma */
|
||||
|
||||
if (*parent_join_count && plan[-1] != '(') {
|
||||
if (*parent_join_count && plan[-1] != '(')
|
||||
{
|
||||
plan_length -= 2;
|
||||
if (plan_length < 0)
|
||||
return false;
|
||||
@ -1846,8 +1815,7 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
|
||||
// put out the join type
|
||||
|
||||
if (rsb_type == isc_info_rsb_cross ||
|
||||
rsb_type == isc_info_rsb_left_cross)
|
||||
if (rsb_type == isc_info_rsb_cross || rsb_type == isc_info_rsb_left_cross)
|
||||
{
|
||||
p = "JOIN (";
|
||||
}
|
||||
@ -1865,7 +1833,8 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
explain_length--;
|
||||
{ // scope to have join_count local.
|
||||
USHORT join_count = (USHORT) * explain++;
|
||||
while (join_count && explain_length > 0 && plan_length > 0) {
|
||||
while (join_count && explain_length > 0 && plan_length > 0)
|
||||
{
|
||||
if (!get_rsb_item(&explain_length, &explain, &plan_length,
|
||||
&plan, &join_count, level_ptr))
|
||||
{
|
||||
@ -1882,8 +1851,7 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
|
||||
if (--plan_length < 0)
|
||||
return false;
|
||||
else
|
||||
*plan++ = ')';
|
||||
*plan++ = ')';
|
||||
|
||||
// this qualifies as a stream, so decrement the join count
|
||||
|
||||
@ -1917,27 +1885,23 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
|
||||
// print out additional index information
|
||||
|
||||
if (rsb_type == isc_info_rsb_indexed ||
|
||||
rsb_type == isc_info_rsb_navigate ||
|
||||
if (rsb_type == isc_info_rsb_indexed || rsb_type == isc_info_rsb_navigate ||
|
||||
rsb_type == isc_info_rsb_ext_indexed)
|
||||
{
|
||||
if (!get_indices(&explain_length, &explain, &plan_length, &plan))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rsb_type == isc_info_rsb_navigate &&
|
||||
*explain == isc_info_rsb_indexed)
|
||||
if (rsb_type == isc_info_rsb_navigate && *explain == isc_info_rsb_indexed)
|
||||
{
|
||||
USHORT idx_count = 1;
|
||||
if (!get_rsb_item(&explain_length, &explain, &plan_length,
|
||||
&plan, &idx_count, level_ptr))
|
||||
if (!get_rsb_item(&explain_length, &explain, &plan_length, &plan, &idx_count, level_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (rsb_type == isc_info_rsb_indexed ||
|
||||
rsb_type == isc_info_rsb_ext_indexed)
|
||||
if (rsb_type == isc_info_rsb_indexed || rsb_type == isc_info_rsb_ext_indexed)
|
||||
{
|
||||
if (--plan_length < 0)
|
||||
return false;
|
||||
@ -1947,10 +1911,11 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
// detect the end of a single relation and put out a final parenthesis
|
||||
|
||||
if (!*parent_join_count)
|
||||
{
|
||||
if (--plan_length < 0)
|
||||
return false;
|
||||
else
|
||||
*plan++ = ')';
|
||||
*plan++ = ')';
|
||||
}
|
||||
|
||||
// this also qualifies as a stream, so decrement the join count
|
||||
|
||||
@ -1965,17 +1930,16 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
substreams at once, and a plan maps to each substream
|
||||
in the union, so the sort doesn't really apply to a particular plan */
|
||||
|
||||
if (explain_length > 2 &&
|
||||
(explain[0] == isc_info_rsb_begin) &&
|
||||
(explain[1] == isc_info_rsb_type) &&
|
||||
(explain[2] == isc_info_rsb_union))
|
||||
if (explain_length > 2 && (explain[0] == isc_info_rsb_begin) &&
|
||||
(explain[1] == isc_info_rsb_type) && (explain[2] == isc_info_rsb_union))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// if this isn't the first item in the list, put out a comma
|
||||
|
||||
if (*parent_join_count && plan[-1] != '(') {
|
||||
if (*parent_join_count && plan[-1] != '(')
|
||||
{
|
||||
plan_length -= 2;
|
||||
if (plan_length < 0)
|
||||
return false;
|
||||
@ -1995,7 +1959,8 @@ static bool get_rsb_item(SSHORT* explain_length_ptr,
|
||||
|
||||
{ // scope to have save_level local.
|
||||
const USHORT save_level = *level_ptr;
|
||||
while (explain_length > 0 && plan_length > 0) {
|
||||
while (explain_length > 0 && plan_length > 0)
|
||||
{
|
||||
if (!get_rsb_item(&explain_length, &explain, &plan_length,
|
||||
&plan, parent_join_count, level_ptr))
|
||||
{
|
||||
@ -2157,14 +2122,13 @@ static void map_in_out( dsql_req* request,
|
||||
|
||||
dsql_par* parameter;
|
||||
|
||||
for (parameter = message->msg_parameters; parameter;
|
||||
parameter = parameter->par_next)
|
||||
for (parameter = message->msg_parameters; parameter; parameter = parameter->par_next)
|
||||
{
|
||||
if (parameter->par_index)
|
||||
{
|
||||
// Make sure the message given to us is long enough
|
||||
|
||||
DSC desc = parameter->par_user_desc;
|
||||
dsc desc = parameter->par_user_desc;
|
||||
USHORT length = (IPTR) desc.dsc_address + desc.dsc_length;
|
||||
if (length > msg_length)
|
||||
break;
|
||||
@ -2222,8 +2186,7 @@ static void map_in_out( dsql_req* request,
|
||||
}
|
||||
|
||||
dsql_par* dbkey;
|
||||
if (request &&
|
||||
((dbkey = request->req_parent_dbkey) != NULL) &&
|
||||
if (request && ((dbkey = request->req_parent_dbkey) != NULL) &&
|
||||
((parameter = request->req_dbkey) != NULL))
|
||||
{
|
||||
MOVD_move(&dbkey->par_desc, ¶meter->par_desc);
|
||||
@ -2236,8 +2199,7 @@ static void map_in_out( dsql_req* request,
|
||||
}
|
||||
|
||||
dsql_par* rec_version;
|
||||
if (request &&
|
||||
((rec_version = request->req_parent_rec_version) != NULL) &&
|
||||
if (request && ((rec_version = request->req_parent_rec_version) != NULL) &&
|
||||
((parameter = request->req_rec_version) != NULL))
|
||||
{
|
||||
MOVD_move(&rec_version->par_desc, ¶meter->par_desc);
|
||||
@ -2264,8 +2226,7 @@ static void map_in_out( dsql_req* request,
|
||||
@param parameters
|
||||
|
||||
**/
|
||||
static USHORT parse_blr(
|
||||
USHORT blr_length,
|
||||
static USHORT parse_blr(USHORT blr_length,
|
||||
const UCHAR* blr, const USHORT msg_length, dsql_par* parameters)
|
||||
{
|
||||
/* If there's no blr length, then the format of the current message buffer
|
||||
@ -2274,8 +2235,7 @@ static USHORT parse_blr(
|
||||
if (!blr_length)
|
||||
{
|
||||
USHORT par_count = 0;
|
||||
for (const dsql_par* parameter = parameters; parameter;
|
||||
parameter = parameter->par_next)
|
||||
for (const dsql_par* parameter = parameters; parameter; parameter = parameter->par_next)
|
||||
{
|
||||
if (parameter->par_index) {
|
||||
++par_count;
|
||||
@ -2572,31 +2532,26 @@ static dsql_req* prepare(thread_db* tdbb, dsql_dbb* database, jrd_tra* transacti
|
||||
Arg::Gds(isc_ddl_not_allowed_by_db_sql_dial) << Arg::Num(statement->req_dbb->dbb_db_SQL_dialect));
|
||||
}
|
||||
|
||||
if (statement->req_type == REQ_COMMIT ||
|
||||
statement->req_type == REQ_COMMIT_RETAIN ||
|
||||
statement->req_type == REQ_ROLLBACK ||
|
||||
statement->req_type == REQ_ROLLBACK_RETAIN)
|
||||
switch (statement->req_type)
|
||||
{
|
||||
case REQ_COMMIT:
|
||||
case REQ_COMMIT_RETAIN:
|
||||
case REQ_ROLLBACK:
|
||||
case REQ_ROLLBACK_RETAIN:
|
||||
return statement;
|
||||
}
|
||||
|
||||
// Work on blob segment statements
|
||||
|
||||
if (statement->req_type == REQ_GET_SEGMENT ||
|
||||
statement->req_type == REQ_PUT_SEGMENT)
|
||||
{
|
||||
case REQ_GET_SEGMENT:
|
||||
case REQ_PUT_SEGMENT:
|
||||
GEN_port(statement, statement->req_blob->blb_open_in_msg);
|
||||
GEN_port(statement, statement->req_blob->blb_open_out_msg);
|
||||
GEN_port(statement, statement->req_blob->blb_segment_msg);
|
||||
return statement;
|
||||
}
|
||||
|
||||
// Generate BLR, DDL or TPB for statement
|
||||
|
||||
// Start transactions takes parameters via a parameter block.
|
||||
// The statement blr string is used for that
|
||||
|
||||
if (statement->req_type == REQ_START_TRANS) {
|
||||
case REQ_START_TRANS:
|
||||
GEN_start_transaction(statement, node);
|
||||
return statement;
|
||||
}
|
||||
@ -2611,8 +2566,7 @@ static dsql_req* prepare(thread_db* tdbb, dsql_dbb* database, jrd_tra* transacti
|
||||
|
||||
// stop here for ddl statements
|
||||
|
||||
if (statement->req_type == REQ_CREATE_DB ||
|
||||
statement->req_type == REQ_DDL)
|
||||
if (statement->req_type == REQ_CREATE_DB || statement->req_type == REQ_DDL)
|
||||
{
|
||||
return statement;
|
||||
}
|
||||
@ -2707,7 +2661,7 @@ static dsql_req* prepare(thread_db* tdbb, dsql_dbb* database, jrd_tra* transacti
|
||||
|
||||
**/
|
||||
static UCHAR* put_item( UCHAR item,
|
||||
USHORT length,
|
||||
const USHORT length,
|
||||
const UCHAR* string,
|
||||
UCHAR* ptr,
|
||||
const UCHAR* const end)
|
||||
@ -2720,16 +2674,13 @@ static UCHAR* put_item( UCHAR item,
|
||||
|
||||
*ptr++ = item;
|
||||
|
||||
*ptr++ = (UCHAR)length;
|
||||
*ptr++ = (UCHAR) length;
|
||||
*ptr++ = length >> 8;
|
||||
|
||||
if (length) {
|
||||
do {
|
||||
*ptr++ = *string++;
|
||||
} while (--length);
|
||||
}
|
||||
if (length)
|
||||
memcpy(ptr, string, length);
|
||||
|
||||
return ptr;
|
||||
return ptr + length;
|
||||
}
|
||||
|
||||
|
||||
@ -2870,19 +2821,20 @@ static void sql_info(thread_db* tdbb,
|
||||
{
|
||||
USHORT length, number;
|
||||
const UCHAR item = *items++;
|
||||
if (item == isc_info_sql_select || item == isc_info_sql_bind)
|
||||
switch (item)
|
||||
{
|
||||
message = (item == isc_info_sql_select) ?
|
||||
&request->req_receive : &request->req_send;
|
||||
case isc_info_sql_select:
|
||||
case isc_info_sql_bind:
|
||||
message = (item == isc_info_sql_select) ? &request->req_receive : &request->req_send;
|
||||
if (info + 1 >= end_info) {
|
||||
*info = isc_info_truncated;
|
||||
return;
|
||||
}
|
||||
*info++ = item;
|
||||
}
|
||||
else if (item == isc_info_sql_stmt_type)
|
||||
{
|
||||
switch (request->req_type) {
|
||||
break;
|
||||
case isc_info_sql_stmt_type:
|
||||
switch (request->req_type)
|
||||
{
|
||||
case REQ_SELECT:
|
||||
case REQ_EMBED_SELECT:
|
||||
number = isc_info_sql_stmt_select;
|
||||
@ -2946,14 +2898,13 @@ static void sql_info(thread_db* tdbb,
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (item == isc_info_sql_sqlda_start) {
|
||||
break;
|
||||
case isc_info_sql_sqlda_start:
|
||||
length = *items++;
|
||||
first_index =
|
||||
static_cast<USHORT>(gds__vax_integer(items, length));
|
||||
first_index = static_cast<USHORT>(gds__vax_integer(items, length));
|
||||
items += length;
|
||||
}
|
||||
else if (item == isc_info_sql_batch_fetch) {
|
||||
break;
|
||||
case isc_info_sql_batch_fetch:
|
||||
if (request->req_flags & REQ_no_batch)
|
||||
number = 0;
|
||||
else
|
||||
@ -2962,77 +2913,74 @@ static void sql_info(thread_db* tdbb,
|
||||
if (!(info = put_item(item, length, buffer, info, end_info))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (item == isc_info_sql_records) {
|
||||
break;
|
||||
case isc_info_sql_records:
|
||||
length = get_request_info(tdbb, request, (SSHORT) sizeof(buffer), buffer);
|
||||
if (length && !(info = put_item(item, length, buffer, info, end_info)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (item == isc_info_sql_get_plan) {
|
||||
/* be careful, get_plan_info() will reallocate the buffer to a
|
||||
larger size if it is not big enough */
|
||||
|
||||
UCHAR* buffer_ptr = buffer;
|
||||
length =
|
||||
get_plan_info(tdbb, request, (SSHORT) sizeof(buffer), reinterpret_cast<SCHAR**>(&buffer_ptr));
|
||||
|
||||
if (length) {
|
||||
info = put_item(item, length, buffer_ptr, info, end_info);
|
||||
}
|
||||
|
||||
if (length > sizeof(buffer)) {
|
||||
gds__free(buffer_ptr);
|
||||
}
|
||||
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!message ||
|
||||
(item != isc_info_sql_num_variables && item != isc_info_sql_describe_vars))
|
||||
{
|
||||
buffer[0] = item;
|
||||
const UCHAR item2 = isc_info_error;
|
||||
length = 1 + convert((SLONG) isc_infunk, buffer + 1);
|
||||
if (!(info = put_item(item2, length, buffer, info, end_info))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
number = (*message) ? (*message)->msg_index : 0;
|
||||
length = convert((SLONG) number, buffer);
|
||||
if (!(info = put_item(item, length, buffer, info, end_info))) {
|
||||
return;
|
||||
}
|
||||
if (item == isc_info_sql_num_variables) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const UCHAR* end_describe = items;
|
||||
while (end_describe < end_items &&
|
||||
*end_describe != isc_info_end &&
|
||||
*end_describe != isc_info_sql_describe_end)
|
||||
break;
|
||||
case isc_info_sql_get_plan:
|
||||
{
|
||||
end_describe++;
|
||||
}
|
||||
// be careful, get_plan_info() will reallocate the buffer to a
|
||||
// larger size if it is not big enough
|
||||
|
||||
info = var_info(*message,
|
||||
items,
|
||||
end_describe,
|
||||
info,
|
||||
end_info,
|
||||
first_index);
|
||||
if (!info) {
|
||||
UCHAR* buffer_ptr = buffer;
|
||||
length = get_plan_info(tdbb, request,
|
||||
(SSHORT) sizeof(buffer), reinterpret_cast<SCHAR**>(&buffer_ptr));
|
||||
|
||||
if (length) {
|
||||
info = put_item(item, length, buffer_ptr, info, end_info);
|
||||
}
|
||||
|
||||
if (length > sizeof(buffer) || buffer_ptr != buffer) {
|
||||
gds__free(buffer_ptr);
|
||||
}
|
||||
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case isc_info_sql_num_variables:
|
||||
case isc_info_sql_describe_vars:
|
||||
if (message)
|
||||
{
|
||||
number = (*message) ? (*message)->msg_index : 0;
|
||||
length = convert((SLONG) number, buffer);
|
||||
if (!(info = put_item(item, length, buffer, info, end_info))) {
|
||||
return;
|
||||
}
|
||||
if (item == isc_info_sql_num_variables) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const UCHAR* end_describe = items;
|
||||
while (end_describe < end_items &&
|
||||
*end_describe != isc_info_end && *end_describe != isc_info_sql_describe_end)
|
||||
{
|
||||
end_describe++;
|
||||
}
|
||||
|
||||
info = var_info(*message, items, end_describe, info, end_info, first_index);
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
|
||||
items = end_describe;
|
||||
if (*items == isc_info_sql_describe_end) {
|
||||
items++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// else fall into
|
||||
default:
|
||||
buffer[0] = item;
|
||||
length = 1 + convert((SLONG) isc_infunk, buffer + 1);
|
||||
if (!(info = put_item(isc_info_error, length, buffer, info, end_info))) {
|
||||
return;
|
||||
}
|
||||
|
||||
items = end_describe;
|
||||
if (*items == isc_info_sql_describe_end) {
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3063,8 +3011,7 @@ static void sql_info(thread_db* tdbb,
|
||||
@param first_index
|
||||
|
||||
**/
|
||||
static UCHAR* var_info(
|
||||
dsql_msg* message,
|
||||
static UCHAR* var_info(dsql_msg* message,
|
||||
const UCHAR* items,
|
||||
const UCHAR* const end_describe,
|
||||
UCHAR* info,
|
||||
@ -3076,8 +3023,7 @@ static UCHAR* var_info(
|
||||
|
||||
Firebird::HalfStaticArray<const dsql_par*, 16> parameters;
|
||||
|
||||
for (const dsql_par* param = message->msg_parameters; param;
|
||||
param = param->par_next)
|
||||
for (const dsql_par* param = message->msg_parameters; param; param = param->par_next)
|
||||
{
|
||||
if (param->par_index)
|
||||
{
|
||||
@ -3146,12 +3092,17 @@ static UCHAR* var_info(
|
||||
case dtype_short:
|
||||
case dtype_long:
|
||||
case dtype_int64:
|
||||
if (param->par_desc.dsc_dtype == dtype_short)
|
||||
switch (param->par_desc.dsc_dtype)
|
||||
{
|
||||
case dtype_short:
|
||||
sql_type = SQL_SHORT;
|
||||
else if (param->par_desc.dsc_dtype == dtype_long)
|
||||
break;
|
||||
case dtype_long:
|
||||
sql_type = SQL_LONG;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
sql_type = SQL_INT64;
|
||||
}
|
||||
sql_scale = param->par_desc.dsc_scale;
|
||||
if (param->par_desc.dsc_sub_type)
|
||||
sql_sub_type = param->par_desc.dsc_sub_type;
|
||||
@ -3176,7 +3127,8 @@ static UCHAR* var_info(
|
||||
const TEXT* name;
|
||||
const UCHAR* buffer = buf;
|
||||
UCHAR item = *describe++;
|
||||
switch (item) {
|
||||
switch (item)
|
||||
{
|
||||
case isc_info_sql_sqlda_seq:
|
||||
length = convert((SLONG) param->par_index, buf);
|
||||
break;
|
||||
|
262
src/dsql/gen.cpp
262
src/dsql/gen.cpp
@ -157,7 +157,8 @@ void GEN_expr(CompiledStatement* statement, dsql_nod* node)
|
||||
UCHAR blr_operator;
|
||||
const dsql_ctx* context;
|
||||
|
||||
switch (node->nod_type) {
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_alias:
|
||||
GEN_expr(statement, node->nod_arg[e_alias_value]);
|
||||
return;
|
||||
@ -471,8 +472,7 @@ void GEN_expr(CompiledStatement* statement, dsql_nod* node)
|
||||
case nod_negate:
|
||||
{
|
||||
dsql_nod* child = node->nod_arg[0];
|
||||
if (child->nod_type == nod_constant &&
|
||||
DTYPE_IS_NUMERIC(child->nod_desc.dsc_dtype))
|
||||
if (child->nod_type == nod_constant && DTYPE_IS_NUMERIC(child->nod_desc.dsc_dtype))
|
||||
{
|
||||
gen_constant(statement, child, NEGATE_VALUE);
|
||||
return;
|
||||
@ -640,8 +640,7 @@ void GEN_expr(CompiledStatement* statement, dsql_nod* node)
|
||||
stuff(statement, blr_operator);
|
||||
|
||||
dsql_nod* const* ptr = node->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + node->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + node->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -651,13 +650,14 @@ void GEN_expr(CompiledStatement* statement, dsql_nod* node)
|
||||
operation in dialect 1. If it is, and if the client dialect is 2,
|
||||
issue a warning about the difference. */
|
||||
|
||||
if (node->nod_type == nod_add2 ||
|
||||
node->nod_type == nod_subtract2 ||
|
||||
node->nod_type == nod_multiply2 ||
|
||||
node->nod_type == nod_divide2 ||
|
||||
node->nod_type == nod_agg_total2 ||
|
||||
node->nod_type == nod_agg_average2)
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_add2:
|
||||
case nod_subtract2:
|
||||
case nod_multiply2:
|
||||
case nod_divide2:
|
||||
case nod_agg_total2:
|
||||
case nod_agg_average2:
|
||||
dsc desc;
|
||||
MAKE_desc(statement, &desc, node, NULL);
|
||||
|
||||
@ -694,7 +694,6 @@ void GEN_expr(CompiledStatement* statement, dsql_nod* node)
|
||||
ERRD_post_warning(Arg::Warning(isc_dsql_dialect_warning_expr) << Arg::Str(s));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -724,8 +723,7 @@ void GEN_port(CompiledStatement* statement, dsql_msg* message)
|
||||
|
||||
ULONG offset = 0;
|
||||
USHORT number = 0;
|
||||
for (parameter = message->msg_parameters; parameter;
|
||||
parameter = parameter->par_next)
|
||||
for (parameter = message->msg_parameters; parameter; parameter = parameter->par_next)
|
||||
{
|
||||
parameter->par_parameter = number++;
|
||||
|
||||
@ -759,8 +757,7 @@ void GEN_port(CompiledStatement* statement, dsql_msg* message)
|
||||
statement->req_dbb->dbb_minor_version) >= ODS_11_1 &&
|
||||
parameter->par_desc.dsc_dtype == dtype_blob &&
|
||||
parameter->par_desc.dsc_sub_type == isc_blob_text &&
|
||||
att->att_charset != CS_NONE &&
|
||||
att->att_charset != CS_BINARY)
|
||||
att->att_charset != CS_NONE && att->att_charset != CS_BINARY)
|
||||
{
|
||||
if (fromCharSet != toCharSet)
|
||||
parameter->par_desc.setTextType(toCharSet);
|
||||
@ -769,7 +766,8 @@ void GEN_port(CompiledStatement* statement, dsql_msg* message)
|
||||
/* For older clients - generate an error should they try and
|
||||
access data types which did not exist in the older dialect */
|
||||
if (statement->req_client_dialect <= SQL_DIALECT_V5)
|
||||
switch (parameter->par_desc.dsc_dtype) {
|
||||
switch (parameter->par_desc.dsc_dtype)
|
||||
{
|
||||
|
||||
/* In V6.0 - older clients, which we distinguish by
|
||||
their use of SQL DIALECT 0 or 1, are forbidden
|
||||
@ -779,8 +777,9 @@ void GEN_port(CompiledStatement* statement, dsql_msg* message)
|
||||
case dtype_int64:
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-804) <<
|
||||
Arg::Gds(isc_dsql_datatype_err) <<
|
||||
Arg::Gds(isc_sql_dialect_datatype_unsupport) << Arg::Num(statement->req_client_dialect) <<
|
||||
Arg::Str(DSC_dtype_tostring(parameter->par_desc.dsc_dtype)));
|
||||
Arg::Gds(isc_sql_dialect_datatype_unsupport) <<
|
||||
Arg::Num(statement->req_client_dialect) <<
|
||||
Arg::Str(DSC_dtype_tostring(parameter->par_desc.dsc_dtype)));
|
||||
break;
|
||||
default:
|
||||
// No special action for other data types
|
||||
@ -810,11 +809,9 @@ void GEN_port(CompiledStatement* statement, dsql_msg* message)
|
||||
|
||||
// Relocate parameter descriptors to point direction into message buffer
|
||||
|
||||
for (parameter = message->msg_parameters; parameter;
|
||||
parameter = parameter->par_next)
|
||||
for (parameter = message->msg_parameters; parameter; parameter = parameter->par_next)
|
||||
{
|
||||
parameter->par_desc.dsc_address = message->msg_buffer +
|
||||
(IPTR)parameter->par_desc.dsc_address;
|
||||
parameter->par_desc.dsc_address = message->msg_buffer + (IPTR) parameter->par_desc.dsc_address;
|
||||
}
|
||||
}
|
||||
|
||||
@ -832,8 +829,7 @@ void GEN_port(CompiledStatement* statement, dsql_msg* message)
|
||||
**/
|
||||
void GEN_request( CompiledStatement* statement, dsql_nod* node)
|
||||
{
|
||||
if (statement->req_type == REQ_CREATE_DB ||
|
||||
statement->req_type == REQ_DDL)
|
||||
if (statement->req_type == REQ_CREATE_DB || statement->req_type == REQ_DDL)
|
||||
{
|
||||
DDL_generate(statement, node);
|
||||
return;
|
||||
@ -932,8 +928,7 @@ void GEN_start_transaction( CompiledStatement* statement, const dsql_nod* tran_n
|
||||
if (!ptr || ptr->nod_type != nod_isolation)
|
||||
continue;
|
||||
|
||||
lock_level = (ptr->nod_flags & NOD_CONSISTENCY) ?
|
||||
isc_tpb_protected : isc_tpb_shared;
|
||||
lock_level = (ptr->nod_flags & NOD_CONSISTENCY) ? isc_tpb_protected : isc_tpb_shared;
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,7 +948,8 @@ void GEN_start_transaction( CompiledStatement* statement, const dsql_nod* tran_n
|
||||
if (!ptr)
|
||||
continue;
|
||||
|
||||
switch (ptr->nod_type) {
|
||||
switch (ptr->nod_type)
|
||||
{
|
||||
case nod_access:
|
||||
if (sw_access)
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
@ -992,8 +988,7 @@ void GEN_start_transaction( CompiledStatement* statement, const dsql_nod* tran_n
|
||||
else {
|
||||
stuff(statement, isc_tpb_read_committed);
|
||||
|
||||
if ((ptr->nod_count) && (ptr->nod_arg[0]) &&
|
||||
(ptr->nod_arg[0]->nod_type == nod_version))
|
||||
if (ptr->nod_count && ptr->nod_arg[0] && ptr->nod_arg[0]->nod_type == nod_version)
|
||||
{
|
||||
if (ptr->nod_arg[0]->nod_flags & NOD_VERSION)
|
||||
stuff(statement, isc_tpb_rec_version);
|
||||
@ -1017,8 +1012,7 @@ void GEN_start_transaction( CompiledStatement* statement, const dsql_nod* tran_n
|
||||
|
||||
if (reserve) {
|
||||
const dsql_nod* const* temp = reserve->nod_arg;
|
||||
for (const dsql_nod* const* end = temp + reserve->nod_count;
|
||||
temp < end; temp++)
|
||||
for (const dsql_nod* const* end = temp + reserve->nod_count; temp < end; temp++)
|
||||
{
|
||||
gen_table_lock(statement, *temp, lock_level);
|
||||
}
|
||||
@ -1081,7 +1075,8 @@ void GEN_statement( CompiledStatement* statement, dsql_nod* node)
|
||||
const dsql_nod* const* end;
|
||||
dsql_str* string;
|
||||
|
||||
switch (node->nod_type) {
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_assign:
|
||||
stuff(statement, blr_assignment);
|
||||
GEN_expr(statement, node->nod_arg[0]);
|
||||
@ -1093,8 +1088,7 @@ void GEN_statement( CompiledStatement* statement, dsql_nod* node)
|
||||
GEN_statement(statement, node->nod_arg[e_blk_action]);
|
||||
if (node->nod_count > 1) {
|
||||
temp = node->nod_arg[e_blk_errs];
|
||||
for (ptr = temp->nod_arg, end = ptr + temp->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_statement(statement, *ptr);
|
||||
}
|
||||
@ -1135,8 +1129,7 @@ void GEN_statement( CompiledStatement* statement, dsql_nod* node)
|
||||
case nod_list:
|
||||
if (!(node->nod_flags & NOD_SIMPLE_LIST))
|
||||
stuff(statement, blr_begin);
|
||||
for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (ptr = node->nod_arg, end = ptr + node->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_statement(statement, *ptr);
|
||||
}
|
||||
@ -1157,8 +1150,7 @@ void GEN_statement( CompiledStatement* statement, dsql_nod* node)
|
||||
stuff(statement, blr_error_handler);
|
||||
temp = node->nod_arg[e_err_errs];
|
||||
stuff_word(statement, temp->nod_count);
|
||||
for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
gen_error_condition(statement, *ptr);
|
||||
}
|
||||
@ -1197,8 +1189,8 @@ void GEN_statement( CompiledStatement* statement, dsql_nod* node)
|
||||
}
|
||||
else
|
||||
stuff(statement, 1); // Singleton
|
||||
for (ptr = temp->nod_arg, end = ptr + temp->nod_count;
|
||||
ptr < end; ptr++)
|
||||
|
||||
for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -1423,8 +1415,7 @@ static void gen_aggregate( CompiledStatement* statement, const dsql_nod* node)
|
||||
if (list != NULL) {
|
||||
stuff(statement, list->nod_count);
|
||||
dsql_nod** ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* end = ptr + list->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (const dsql_nod* const* end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -1486,8 +1477,7 @@ static void gen_coalesce( CompiledStatement* statement, const dsql_nod* node)
|
||||
stuff(statement, blr_cast);
|
||||
GEN_descriptor(statement, &node->nod_desc, true);
|
||||
dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + (list->nod_count - 1);
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + (list->nod_count - 1); ptr < end; ptr++)
|
||||
{
|
||||
// IF (expression IS NULL) THEN
|
||||
stuff(statement, blr_value_if);
|
||||
@ -1528,7 +1518,8 @@ static void gen_constant( CompiledStatement* statement, const dsc* desc, bool ne
|
||||
|
||||
const UCHAR* p = desc->dsc_address;
|
||||
|
||||
switch (desc->dsc_dtype) {
|
||||
switch (desc->dsc_dtype)
|
||||
{
|
||||
case dtype_short:
|
||||
GEN_descriptor(statement, desc, true);
|
||||
value = *(SSHORT *) p;
|
||||
@ -1581,7 +1572,8 @@ static void gen_constant( CompiledStatement* statement, const dsc* desc, bool ne
|
||||
|
||||
if (negate_value)
|
||||
i64value = -i64value;
|
||||
else if (i64value == MIN_SINT64) {
|
||||
else if (i64value == MIN_SINT64)
|
||||
{
|
||||
/* UH OH!
|
||||
* yylex correctly recognized the digits as the most-negative
|
||||
* possible INT64 value, but unfortunately, there was no
|
||||
@ -1601,14 +1593,12 @@ static void gen_constant( CompiledStatement* statement, const dsc* desc, bool ne
|
||||
* it that way, else as an INT64.
|
||||
*/
|
||||
|
||||
if ((i64value >= (SINT64) MIN_SLONG) &&
|
||||
(i64value <= (SINT64) MAX_SLONG))
|
||||
if ((i64value >= (SINT64) MIN_SLONG) && (i64value <= (SINT64) MAX_SLONG))
|
||||
{
|
||||
stuff(statement, blr_long);
|
||||
stuff(statement, desc->dsc_scale);
|
||||
stuff_word(statement, i64value);
|
||||
stuff_word(statement, i64value >> 16);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
stuff(statement, blr_int64);
|
||||
@ -1686,7 +1676,8 @@ static void gen_constant( CompiledStatement* statement, dsql_nod* node, bool neg
|
||||
**/
|
||||
void GEN_descriptor( CompiledStatement* statement, const dsc* desc, bool texttype)
|
||||
{
|
||||
switch (desc->dsc_dtype) {
|
||||
switch (desc->dsc_dtype)
|
||||
{
|
||||
case dtype_text:
|
||||
if (texttype || desc->dsc_ttype() == ttype_binary || desc->dsc_ttype() == ttype_none) {
|
||||
stuff(statement, blr_text2);
|
||||
@ -1786,7 +1777,8 @@ static void gen_error_condition( CompiledStatement* statement, const dsql_nod* n
|
||||
{
|
||||
const dsql_str* string;
|
||||
|
||||
switch (node->nod_type) {
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_sqlcode:
|
||||
stuff(statement, blr_sql_code);
|
||||
stuff_word(statement, (USHORT)(IPTR) node->nod_arg[0]);
|
||||
@ -1935,15 +1927,18 @@ static void gen_field( CompiledStatement* statement, const dsql_ctx* context,
|
||||
{
|
||||
/* For older clients - generate an error should they try and
|
||||
* access data types which did not exist in the older dialect */
|
||||
if (statement->req_client_dialect <= SQL_DIALECT_V5) {
|
||||
switch (field->fld_dtype) {
|
||||
if (statement->req_client_dialect <= SQL_DIALECT_V5)
|
||||
{
|
||||
switch (field->fld_dtype)
|
||||
{
|
||||
case dtype_sql_date:
|
||||
case dtype_sql_time:
|
||||
case dtype_int64:
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-804) <<
|
||||
Arg::Gds(isc_dsql_datatype_err) <<
|
||||
Arg::Gds(isc_sql_dialect_datatype_unsupport) << Arg::Num(statement->req_client_dialect) <<
|
||||
Arg::Str(DSC_dtype_tostring(static_cast<UCHAR>(field->fld_dtype))));
|
||||
Arg::Gds(isc_sql_dialect_datatype_unsupport) <<
|
||||
Arg::Num(statement->req_client_dialect) <<
|
||||
Arg::Str(DSC_dtype_tostring(static_cast<UCHAR>(field->fld_dtype))));
|
||||
break;
|
||||
default:
|
||||
// No special action for other data types
|
||||
@ -1968,8 +1963,7 @@ static void gen_field( CompiledStatement* statement, const dsql_ctx* context,
|
||||
if (indices) {
|
||||
stuff(statement, indices->nod_count);
|
||||
dsql_nod** ptr = indices->nod_arg;
|
||||
for (const dsql_nod* const* end = ptr + indices->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* end = ptr + indices->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -2034,8 +2028,7 @@ static void gen_for_select( CompiledStatement* statement, const dsql_nod* for_se
|
||||
Arg::Gds(isc_dsql_count_mismatch));
|
||||
dsql_nod** ptr = list->nod_arg;
|
||||
dsql_nod** ptr_to = list_to->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end;
|
||||
ptr++, ptr_to++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++, ptr_to++)
|
||||
{
|
||||
stuff(statement, blr_assignment);
|
||||
GEN_expr(statement, *ptr);
|
||||
@ -2090,7 +2083,8 @@ static void gen_join_rse( CompiledStatement* statement, const dsql_nod* rse)
|
||||
GEN_expr(statement, rse->nod_arg[e_join_rght_rel]);
|
||||
|
||||
const dsql_nod* node = rse->nod_arg[e_join_type];
|
||||
if (node->nod_type != nod_join_inner) {
|
||||
if (node->nod_type != nod_join_inner)
|
||||
{
|
||||
stuff(statement, blr_join_type);
|
||||
if (node->nod_type == nod_join_left)
|
||||
stuff(statement, blr_left);
|
||||
@ -2204,8 +2198,7 @@ static void gen_plan( CompiledStatement* statement, const dsql_nod* plan_express
|
||||
// stuff one or more plan items
|
||||
|
||||
const dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
const dsql_nod* node = *ptr;
|
||||
if (node->nod_type == nod_plan_expr) {
|
||||
@ -2227,7 +2220,8 @@ static void gen_plan( CompiledStatement* statement, const dsql_nod* plan_express
|
||||
const dsql_str* index_string;
|
||||
|
||||
arg = node->nod_arg[1];
|
||||
switch (arg->nod_type) {
|
||||
switch (arg->nod_type)
|
||||
{
|
||||
case nod_natural:
|
||||
stuff(statement, blr_sequential);
|
||||
break;
|
||||
@ -2243,12 +2237,10 @@ static void gen_plan( CompiledStatement* statement, const dsql_nod* plan_express
|
||||
case nod_index:
|
||||
{
|
||||
stuff(statement, blr_indices);
|
||||
arg = (arg->nod_type == nod_index) ?
|
||||
arg->nod_arg[0] : arg->nod_arg[1];
|
||||
arg = (arg->nod_type == nod_index) ? arg->nod_arg[0] : arg->nod_arg[1];
|
||||
stuff(statement, arg->nod_count);
|
||||
const dsql_nod* const* ptr2 = arg->nod_arg;
|
||||
for (const dsql_nod* const* const end2 = ptr2 + arg->nod_count;
|
||||
ptr2 < end2; ptr2++)
|
||||
for (const dsql_nod* const* const end2 = ptr2 + arg->nod_count; ptr2 < end2; ptr2++)
|
||||
{
|
||||
index_string = (dsql_str*) * ptr2;
|
||||
stuff_cstring(statement, index_string->str_data);
|
||||
@ -2283,7 +2275,8 @@ static void gen_relation( CompiledStatement* statement, dsql_ctx* context)
|
||||
const dsql_prc* procedure = context->ctx_procedure;
|
||||
|
||||
// if this is a trigger or procedure, don't want relation id used
|
||||
if (relation) {
|
||||
if (relation)
|
||||
{
|
||||
if (DDL_ids(statement)) {
|
||||
if (context->ctx_alias)
|
||||
stuff(statement, blr_rid2);
|
||||
@ -2304,7 +2297,8 @@ static void gen_relation( CompiledStatement* statement, dsql_ctx* context)
|
||||
|
||||
stuff_context(statement, context);
|
||||
}
|
||||
else if (procedure) {
|
||||
else if (procedure)
|
||||
{
|
||||
if (DDL_ids(statement)) {
|
||||
stuff(statement, blr_pid);
|
||||
stuff_word(statement, procedure->prc_id);
|
||||
@ -2320,8 +2314,7 @@ static void gen_relation( CompiledStatement* statement, dsql_ctx* context)
|
||||
stuff_word(statement, inputs->nod_count);
|
||||
|
||||
dsql_nod* const* ptr = inputs->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + inputs->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + inputs->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -2348,6 +2341,7 @@ void GEN_return( CompiledStatement* statement, const dsql_nod* parameters, bool
|
||||
{
|
||||
if (!eos_flag)
|
||||
stuff(statement, blr_begin);
|
||||
|
||||
stuff(statement, blr_send);
|
||||
stuff(statement, 1);
|
||||
stuff(statement, blr_begin);
|
||||
@ -2355,8 +2349,7 @@ void GEN_return( CompiledStatement* statement, const dsql_nod* parameters, bool
|
||||
USHORT outputs = 0;
|
||||
if (parameters) {
|
||||
const dsql_nod* const* ptr = parameters->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + parameters->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + parameters->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
outputs++;
|
||||
const dsql_nod* parameter = *ptr;
|
||||
@ -2417,21 +2410,23 @@ static void gen_rse( CompiledStatement* statement, const dsql_nod* rse)
|
||||
stuff(statement, 1);
|
||||
gen_union(statement, rse);
|
||||
}
|
||||
else if (list->nod_type == nod_list) {
|
||||
else if (list->nod_type == nod_list)
|
||||
{
|
||||
stuff(statement, list->nod_count);
|
||||
dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_nod* node = *ptr;
|
||||
if (node->nod_type == nod_relation ||
|
||||
node->nod_type == nod_aggregate ||
|
||||
node->nod_type == nod_join)
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_relation:
|
||||
case nod_aggregate:
|
||||
case nod_join:
|
||||
GEN_expr(statement, node);
|
||||
}
|
||||
else if (node->nod_type == nod_derived_table) {
|
||||
break;
|
||||
case nod_derived_table:
|
||||
GEN_expr(statement, node->nod_arg[e_derived_table_rse]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2467,8 +2462,7 @@ static void gen_rse( CompiledStatement* statement, const dsql_nod* rse)
|
||||
stuff(statement, blr_project);
|
||||
stuff(statement, list->nod_count);
|
||||
dsql_nod** ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -2488,8 +2482,7 @@ static void gen_rse( CompiledStatement* statement, const dsql_nod* rse)
|
||||
and offset to scroll; note that we do this only on a SELECT
|
||||
type statement and only when talking to a 4.1 engine or greater */
|
||||
|
||||
if (statement->req_type == REQ_SELECT &&
|
||||
statement->req_dbb->dbb_base_level >= 5)
|
||||
if (statement->req_type == REQ_SELECT && statement->req_dbb->dbb_base_level >= 5)
|
||||
{
|
||||
stuff(statement, blr_receive);
|
||||
stuff(statement, statement->req_async->msg_number);
|
||||
@ -2521,14 +2514,12 @@ static void gen_searched_case( CompiledStatement* statement, const dsql_nod* nod
|
||||
|
||||
stuff(statement, blr_cast);
|
||||
GEN_descriptor(statement, &node->nod_desc, true);
|
||||
const SSHORT count =
|
||||
node->nod_arg[e_searched_case_search_conditions]->nod_count;
|
||||
const SSHORT count = node->nod_arg[e_searched_case_search_conditions]->nod_count;
|
||||
dsql_nod* boolean_list = node->nod_arg[e_searched_case_search_conditions];
|
||||
dsql_nod* results_list = node->nod_arg[e_searched_case_results];
|
||||
dsql_nod* const* bptr = boolean_list->nod_arg;
|
||||
dsql_nod* const* rptr = results_list->nod_arg;
|
||||
for (const dsql_nod* const* const end = bptr + count; bptr < end;
|
||||
bptr++, rptr++)
|
||||
for (const dsql_nod* const* const end = bptr + count; bptr < end; bptr++, rptr++)
|
||||
{
|
||||
stuff(statement, blr_value_if);
|
||||
GEN_expr(statement, *bptr);
|
||||
@ -2560,19 +2551,16 @@ static void gen_select( CompiledStatement* statement, dsql_nod* rse)
|
||||
// Set up parameter for things in the select list
|
||||
const dsql_nod* list = rse->nod_arg[e_rse_items];
|
||||
dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_par* parameter =
|
||||
MAKE_parameter(statement->req_receive, true, true, 0, *ptr);
|
||||
dsql_par* parameter = MAKE_parameter(statement->req_receive, true, true, 0, *ptr);
|
||||
parameter->par_node = *ptr;
|
||||
MAKE_desc(statement, ¶meter->par_desc, *ptr, NULL);
|
||||
}
|
||||
|
||||
// Set up parameter to handle EOF
|
||||
|
||||
dsql_par* parameter_eof =
|
||||
MAKE_parameter(statement->req_receive, false, false, 0, NULL);
|
||||
dsql_par* parameter_eof = MAKE_parameter(statement->req_receive, false, false, 0, NULL);
|
||||
statement->req_eof = parameter_eof;
|
||||
parameter_eof->par_desc.dsc_dtype = dtype_short;
|
||||
parameter_eof->par_desc.dsc_scale = 0;
|
||||
@ -2582,35 +2570,31 @@ static void gen_select( CompiledStatement* statement, dsql_nod* rse)
|
||||
|
||||
list = rse->nod_arg[e_rse_streams];
|
||||
|
||||
if (!rse->nod_arg[e_rse_reduced]) {
|
||||
if (!rse->nod_arg[e_rse_reduced])
|
||||
{
|
||||
dsql_nod* const* ptr2 = list->nod_arg;
|
||||
for (const dsql_nod* const* const end2 = ptr2 + list->nod_count;
|
||||
ptr2 < end2; ptr2++)
|
||||
for (const dsql_nod* const* const end2 = ptr2 + list->nod_count; ptr2 < end2; ptr2++)
|
||||
{
|
||||
dsql_nod* item = *ptr2;
|
||||
if (item && item->nod_type == nod_relation) {
|
||||
if (item && item->nod_type == nod_relation)
|
||||
{
|
||||
context = (dsql_ctx*) item->nod_arg[e_rel_context];
|
||||
if (relation = context->ctx_relation) {
|
||||
if (relation = context->ctx_relation)
|
||||
{
|
||||
// Set up dbkey
|
||||
dsql_par* parameter =
|
||||
MAKE_parameter(statement->req_receive,
|
||||
false, false, 0, NULL);
|
||||
dsql_par* parameter = MAKE_parameter(statement->req_receive, false, false, 0, NULL);
|
||||
parameter->par_dbkey_ctx = context;
|
||||
parameter->par_desc.dsc_dtype = dtype_text;
|
||||
parameter->par_desc.dsc_ttype() = ttype_binary;
|
||||
parameter->par_desc.dsc_length =
|
||||
relation->rel_dbkey_length;
|
||||
parameter->par_desc.dsc_length = relation->rel_dbkey_length;
|
||||
|
||||
// Set up record version - for post v33 databases
|
||||
|
||||
parameter =
|
||||
MAKE_parameter(statement->req_receive, false,
|
||||
false, 0, NULL);
|
||||
parameter = MAKE_parameter(statement->req_receive, false, false, 0, NULL);
|
||||
parameter->par_rec_version_ctx = context;
|
||||
parameter->par_desc.dsc_dtype = dtype_text;
|
||||
parameter->par_desc.dsc_ttype() = ttype_binary;
|
||||
parameter->par_desc.dsc_length =
|
||||
relation->rel_dbkey_length / 2;
|
||||
parameter->par_desc.dsc_length = relation->rel_dbkey_length / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2620,19 +2604,16 @@ static void gen_select( CompiledStatement* statement, dsql_nod* rse)
|
||||
/* define the parameters for the scrolling message--offset and direction,
|
||||
in that order to make it easier to generate the statement */
|
||||
|
||||
if (statement->req_type == REQ_SELECT &&
|
||||
statement->req_dbb->dbb_base_level >= 5)
|
||||
if (statement->req_type == REQ_SELECT && statement->req_dbb->dbb_base_level >= 5)
|
||||
{
|
||||
dsql_par* parameter =
|
||||
MAKE_parameter(statement->req_async, false, false, 0, NULL);
|
||||
dsql_par* parameter = MAKE_parameter(statement->req_async, false, false, 0, NULL);
|
||||
parameter->par_desc.dsc_dtype = dtype_short;
|
||||
parameter->par_desc.dsc_length = sizeof(USHORT);
|
||||
parameter->par_desc.dsc_scale = 0;
|
||||
parameter->par_desc.dsc_flags = 0;
|
||||
parameter->par_desc.dsc_sub_type = 0;
|
||||
|
||||
parameter =
|
||||
MAKE_parameter(statement->req_async, false, false, 0, NULL);
|
||||
parameter = MAKE_parameter(statement->req_async, false, false, 0, NULL);
|
||||
parameter->par_desc.dsc_dtype = dtype_long;
|
||||
parameter->par_desc.dsc_length = sizeof(ULONG);
|
||||
parameter->par_desc.dsc_scale = 0;
|
||||
@ -2650,9 +2631,8 @@ static void gen_select( CompiledStatement* statement, dsql_nod* rse)
|
||||
else
|
||||
statement->req_send = NULL;
|
||||
#ifdef SCROLLABLE_CURSORS
|
||||
if (statement->req_type == REQ_SELECT &&
|
||||
statement->req_dbb->dbb_base_level >= 5)
|
||||
GEN_port(statement, statement->req_async);
|
||||
if (statement->req_type == REQ_SELECT && statement->req_dbb->dbb_base_level >= 5)
|
||||
GEN_port(statement, statement->req_async);
|
||||
#endif
|
||||
|
||||
// If there is a send message, build a RECEIVE
|
||||
@ -2692,8 +2672,7 @@ static void gen_select( CompiledStatement* statement, dsql_nod* rse)
|
||||
gen_constant(statement, &constant_desc, USE_VALUE);
|
||||
gen_parameter(statement, statement->req_eof);
|
||||
|
||||
for (dsql_par* parameter = message->msg_parameters; parameter;
|
||||
parameter = parameter->par_next)
|
||||
for (dsql_par* parameter = message->msg_parameters; parameter; parameter = parameter->par_next)
|
||||
{
|
||||
if (parameter->par_node) {
|
||||
stuff(statement, blr_assignment);
|
||||
@ -2747,8 +2726,7 @@ static void gen_simple_case( CompiledStatement* statement, const dsql_nod* node)
|
||||
|
||||
dsql_nod* const* wptr = when_list->nod_arg;
|
||||
dsql_nod* const* rptr = results_list->nod_arg;
|
||||
for (const dsql_nod* const* const end = wptr + count; wptr < end;
|
||||
wptr++, rptr++)
|
||||
for (const dsql_nod* const* const end = wptr + count; wptr < end; wptr++, rptr++)
|
||||
{
|
||||
stuff(statement, blr_value_if);
|
||||
stuff(statement, blr_eql);
|
||||
@ -2779,12 +2757,13 @@ static void gen_sort( CompiledStatement* statement, dsql_nod* list)
|
||||
stuff(statement, list->nod_count);
|
||||
|
||||
dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_nod* nulls_placement = (*ptr)->nod_arg[e_order_nulls];
|
||||
if (nulls_placement) {
|
||||
switch (nulls_placement->getSlong()) {
|
||||
if (nulls_placement)
|
||||
{
|
||||
switch (nulls_placement->getSlong())
|
||||
{
|
||||
case NOD_NULLS_FIRST:
|
||||
stuff(statement, blr_nullsfirst);
|
||||
break;
|
||||
@ -2819,7 +2798,8 @@ static void gen_statement(CompiledStatement* statement, const dsql_nod* node)
|
||||
const dsql_msg* message = NULL;
|
||||
bool send_before_for = !(statement->req_flags & REQ_dsql_upd_or_ins);
|
||||
|
||||
switch (node->nod_type) {
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_store:
|
||||
rse = node->nod_arg[e_sto_rse];
|
||||
break;
|
||||
@ -2866,7 +2846,8 @@ static void gen_statement(CompiledStatement* statement, const dsql_nod* node)
|
||||
const dsql_ctx* context;
|
||||
const dsql_str* name;
|
||||
|
||||
switch (node->nod_type) {
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_store:
|
||||
stuff(statement, node->nod_arg[e_sto_return] ? blr_store2 : blr_store);
|
||||
GEN_expr(statement, node->nod_arg[e_sto_relation]);
|
||||
@ -2998,8 +2979,7 @@ static void gen_sys_function(CompiledStatement* statement, const dsql_nod* node)
|
||||
{
|
||||
stuff(statement, list->nod_count);
|
||||
dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -3022,8 +3002,7 @@ static void gen_sys_function(CompiledStatement* statement, const dsql_nod* node)
|
||||
@param lock_level
|
||||
|
||||
**/
|
||||
static void gen_table_lock( CompiledStatement* statement, const dsql_nod* tbl_lock,
|
||||
USHORT lock_level)
|
||||
static void gen_table_lock( CompiledStatement* statement, const dsql_nod* tbl_lock, USHORT lock_level)
|
||||
{
|
||||
if (!tbl_lock || tbl_lock->nod_type != nod_table_lock)
|
||||
return;
|
||||
@ -3043,8 +3022,7 @@ static void gen_table_lock( CompiledStatement* statement, const dsql_nod* tbl_lo
|
||||
isc_tpb_lock_write : isc_tpb_lock_read;
|
||||
|
||||
const dsql_nod* const* ptr = tbl_names->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + tbl_names->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + tbl_names->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
if ((*ptr)->nod_type != nod_relation_name)
|
||||
continue;
|
||||
@ -3078,11 +3056,11 @@ static void gen_udf( CompiledStatement* statement, const dsql_nod* node)
|
||||
stuff_string(statement, userFunc->udf_name);
|
||||
|
||||
const dsql_nod* list;
|
||||
if ((node->nod_count == 2) && (list = node->nod_arg[1])) {
|
||||
if ((node->nod_count == 2) && (list = node->nod_arg[1]))
|
||||
{
|
||||
stuff(statement, list->nod_count);
|
||||
dsql_nod* const* ptr = list->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count;
|
||||
ptr < end; ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + list->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
GEN_expr(statement, *ptr);
|
||||
}
|
||||
@ -3128,8 +3106,7 @@ static void gen_union( CompiledStatement* statement, const dsql_nod* union_node)
|
||||
stuff(statement, streams->nod_count); // number of substreams
|
||||
|
||||
dsql_nod** ptr = streams->nod_arg;
|
||||
for (const dsql_nod* const* const end = ptr + streams->nod_count; ptr < end;
|
||||
ptr++)
|
||||
for (const dsql_nod* const* const end = ptr + streams->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_nod* sub_rse = *ptr;
|
||||
gen_rse(statement, sub_rse);
|
||||
@ -3138,8 +3115,7 @@ static void gen_union( CompiledStatement* statement, const dsql_nod* union_node)
|
||||
stuff_word(statement, items->nod_count);
|
||||
USHORT count = 0;
|
||||
dsql_nod** iptr = items->nod_arg;
|
||||
for (const dsql_nod* const* const iend = iptr + items->nod_count;
|
||||
iptr < iend; iptr++)
|
||||
for (const dsql_nod* const* const iend = iptr + items->nod_count; iptr < iend; iptr++)
|
||||
{
|
||||
stuff_word(statement, count);
|
||||
GEN_expr(statement, *iptr);
|
||||
|
@ -274,7 +274,8 @@ dsql_nod* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag)
|
||||
{
|
||||
// Setup the constant's descriptor
|
||||
|
||||
switch (numeric_flag) {
|
||||
switch (numeric_flag)
|
||||
{
|
||||
case CONSTANT_DATE:
|
||||
node->nod_desc.dsc_dtype = dtype_sql_date;
|
||||
break;
|
||||
@ -313,8 +314,7 @@ dsql_nod* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag)
|
||||
node->nod_desc.dsc_dtype = dtype_text;
|
||||
node->nod_desc.dsc_sub_type = 0;
|
||||
node->nod_desc.dsc_scale = 0;
|
||||
node->nod_desc.dsc_length =
|
||||
static_cast<USHORT>(constant->str_length);
|
||||
node->nod_desc.dsc_length = static_cast<USHORT>(constant->str_length);
|
||||
node->nod_desc.dsc_address = (UCHAR*) constant->str_data;
|
||||
node->nod_desc.dsc_ttype() = ttype_dynamic;
|
||||
// carry a pointer to the constant to resolve character set in pass1
|
||||
@ -419,7 +419,8 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
return;
|
||||
}
|
||||
|
||||
switch (node->nod_type) {
|
||||
switch (node->nod_type)
|
||||
{
|
||||
case nod_constant:
|
||||
case nod_variable:
|
||||
*desc = node->nod_desc;
|
||||
@ -450,8 +451,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
case nod_agg_average:
|
||||
MAKE_desc(statement, desc, node->nod_arg[0], null_replacement);
|
||||
desc->dsc_flags = DSC_nullable;
|
||||
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype) &&
|
||||
!DTYPE_IS_TEXT(desc->dsc_dtype))
|
||||
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype) && !DTYPE_IS_TEXT(desc->dsc_dtype))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_dsql_agg_wrongarg) << Arg::Str("AVG"));
|
||||
@ -483,8 +483,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
|
||||
case nod_agg_total:
|
||||
MAKE_desc(statement, desc, node->nod_arg[0], null_replacement);
|
||||
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype) &&
|
||||
!DTYPE_IS_TEXT(desc->dsc_dtype))
|
||||
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype) && !DTYPE_IS_TEXT(desc->dsc_dtype))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_dsql_agg_wrongarg) << Arg::Str("SUM"));
|
||||
@ -628,8 +627,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
MAKE_desc(statement, &desc1, node->nod_arg[0], node->nod_arg[1]);
|
||||
MAKE_desc(statement, &desc2, node->nod_arg[1], node->nod_arg[0]);
|
||||
|
||||
if (node->nod_arg[0]->nod_type == nod_null &&
|
||||
node->nod_arg[1]->nod_type == nod_null)
|
||||
if (node->nod_arg[0]->nod_type == nod_null && node->nod_arg[1]->nod_type == nod_null)
|
||||
{
|
||||
// NULL + NULL = NULL of INT
|
||||
make_null(desc);
|
||||
@ -653,13 +651,13 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
|
||||
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
|
||||
|
||||
switch (dtype) {
|
||||
switch (dtype)
|
||||
{
|
||||
case dtype_sql_time:
|
||||
case dtype_sql_date:
|
||||
// CVC: I don't see how this case can happen since dialect 1 doesn't accept DATE or TIME
|
||||
// Forbid <date/time> +- <string>
|
||||
if (DTYPE_IS_TEXT(desc1.dsc_dtype) ||
|
||||
DTYPE_IS_TEXT(desc2.dsc_dtype))
|
||||
if (DTYPE_IS_TEXT(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc2.dsc_dtype))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_expression_eval_err) <<
|
||||
Arg::Gds(isc_dsql_nodateortime_pm_string));
|
||||
@ -690,13 +688,11 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
dtype = dtype_timestamp;
|
||||
else if (desc1.dsc_dtype == desc2.dsc_dtype)
|
||||
dtype = desc1.dsc_dtype;
|
||||
else if ((desc1.dsc_dtype == dtype_timestamp) &&
|
||||
(desc2.dsc_dtype == dtype_sql_date))
|
||||
else if ((desc1.dsc_dtype == dtype_timestamp) && (desc2.dsc_dtype == dtype_sql_date))
|
||||
{
|
||||
dtype = dtype_timestamp;
|
||||
}
|
||||
else if ((desc2.dsc_dtype == dtype_timestamp) &&
|
||||
(desc1.dsc_dtype == dtype_sql_date))
|
||||
else if ((desc2.dsc_dtype == dtype_timestamp) && (desc1.dsc_dtype == dtype_sql_date))
|
||||
{
|
||||
dtype = dtype_timestamp;
|
||||
}
|
||||
@ -782,8 +778,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
MAKE_desc(statement, &desc1, node->nod_arg[0], node->nod_arg[1]);
|
||||
MAKE_desc(statement, &desc2, node->nod_arg[1], node->nod_arg[0]);
|
||||
|
||||
if (node->nod_arg[0]->nod_type == nod_null &&
|
||||
node->nod_arg[1]->nod_type == nod_null)
|
||||
if (node->nod_arg[0]->nod_type == nod_null && node->nod_arg[1]->nod_type == nod_null)
|
||||
{
|
||||
// NULL + NULL = NULL of INT
|
||||
make_null(desc);
|
||||
@ -835,7 +830,8 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
|
||||
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
|
||||
|
||||
switch (dtype) {
|
||||
switch (dtype)
|
||||
{
|
||||
case dtype_sql_time:
|
||||
case dtype_sql_date:
|
||||
case dtype_timestamp:
|
||||
@ -960,8 +956,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
MAKE_desc(statement, &desc1, node->nod_arg[0], node->nod_arg[1]);
|
||||
MAKE_desc(statement, &desc2, node->nod_arg[1], node->nod_arg[0]);
|
||||
|
||||
if (node->nod_arg[0]->nod_type == nod_null &&
|
||||
node->nod_arg[1]->nod_type == nod_null)
|
||||
if (node->nod_arg[0]->nod_type == nod_null && node->nod_arg[1]->nod_type == nod_null)
|
||||
{
|
||||
// NULL * NULL = NULL of INT
|
||||
make_null(desc);
|
||||
@ -977,7 +972,8 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
dtype = DSC_multiply_blr4_result[desc1.dsc_dtype][desc2.dsc_dtype];
|
||||
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
|
||||
|
||||
switch (dtype) {
|
||||
switch (dtype)
|
||||
{
|
||||
case dtype_double:
|
||||
desc->dsc_dtype = dtype_double;
|
||||
desc->dsc_sub_type = 0;
|
||||
@ -1002,8 +998,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
MAKE_desc(statement, &desc1, node->nod_arg[0], node->nod_arg[1]);
|
||||
MAKE_desc(statement, &desc2, node->nod_arg[1], node->nod_arg[0]);
|
||||
|
||||
if (node->nod_arg[0]->nod_type == nod_null &&
|
||||
node->nod_arg[1]->nod_type == nod_null)
|
||||
if (node->nod_arg[0]->nod_type == nod_null && node->nod_arg[1]->nod_type == nod_null)
|
||||
{
|
||||
// NULL * NULL = NULL of INT
|
||||
make_null(desc);
|
||||
@ -1027,7 +1022,8 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
dtype = DSC_multiply_result[desc1.dsc_dtype][desc2.dsc_dtype];
|
||||
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
|
||||
|
||||
switch (dtype) {
|
||||
switch (dtype)
|
||||
{
|
||||
case dtype_double:
|
||||
desc->dsc_dtype = dtype_double;
|
||||
desc->dsc_sub_type = 0;
|
||||
@ -1063,8 +1059,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
MAKE_desc(statement, &desc1, node->nod_arg[0], node->nod_arg[1]);
|
||||
MAKE_desc(statement, &desc2, node->nod_arg[1], node->nod_arg[0]);
|
||||
|
||||
if (node->nod_arg[0]->nod_type == nod_null &&
|
||||
node->nod_arg[1]->nod_type == nod_null)
|
||||
if (node->nod_arg[0]->nod_type == nod_null && node->nod_arg[1]->nod_type == nod_null)
|
||||
{
|
||||
// NULL / NULL = NULL of INT
|
||||
make_null(desc);
|
||||
@ -1102,8 +1097,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
MAKE_desc(statement, &desc1, node->nod_arg[0], node->nod_arg[1]);
|
||||
MAKE_desc(statement, &desc2, node->nod_arg[1], node->nod_arg[0]);
|
||||
|
||||
if (node->nod_arg[0]->nod_type == nod_null &&
|
||||
node->nod_arg[1]->nod_type == nod_null)
|
||||
if (node->nod_arg[0]->nod_type == nod_null && node->nod_arg[1]->nod_type == nod_null)
|
||||
{
|
||||
// NULL / NULL = NULL of INT
|
||||
make_null(desc);
|
||||
@ -1128,7 +1122,8 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
desc->dsc_dtype = static_cast<UCHAR>(dtype);
|
||||
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
|
||||
|
||||
switch (dtype) {
|
||||
switch (dtype)
|
||||
{
|
||||
case dtype_int64:
|
||||
desc->dsc_length = sizeof(SINT64);
|
||||
desc->dsc_scale = NUMERIC_SCALE(desc1) + NUMERIC_SCALE(desc2);
|
||||
@ -1233,7 +1228,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
fb_assert(nodeArgs->nod_type == nod_list);
|
||||
|
||||
for (dsql_nod** p = nodeArgs->nod_arg;
|
||||
p < nodeArgs->nod_arg + nodeArgs->nod_count; ++p)
|
||||
p < nodeArgs->nod_arg + nodeArgs->nod_count; ++p)
|
||||
{
|
||||
MAKE_desc(statement, &(*p)->nod_desc, *p, NULL);
|
||||
args.add(&(*p)->nod_desc);
|
||||
@ -1299,8 +1294,7 @@ void MAKE_desc(CompiledStatement* statement, dsc* desc, dsql_nod* node, dsql_nod
|
||||
desc->dsc_flags = 0;
|
||||
desc->dsc_ttype() = ttype_metadata;
|
||||
desc->dsc_length =
|
||||
USERNAME_LENGTH * METD_get_charset_bpc(statement, ttype_metadata) +
|
||||
sizeof(USHORT);
|
||||
USERNAME_LENGTH * METD_get_charset_bpc(statement, ttype_metadata) + sizeof(USHORT);
|
||||
return;
|
||||
|
||||
case nod_internal_info:
|
||||
@ -1457,8 +1451,7 @@ void MAKE_desc_from_field(dsc* desc, const dsql_fld* field)
|
||||
desc->dsc_length = field->fld_length;
|
||||
desc->dsc_flags = (field->fld_flags & FLD_nullable) ? DSC_nullable : 0;
|
||||
if (desc->dsc_dtype <= dtype_any_text) {
|
||||
INTL_ASSIGN_DSC(desc, field->fld_character_set_id,
|
||||
field->fld_collation_id);
|
||||
INTL_ASSIGN_DSC(desc, field->fld_character_set_id, field->fld_collation_id);
|
||||
}
|
||||
else if (desc->dsc_dtype == dtype_blob)
|
||||
{
|
||||
@ -1529,12 +1522,12 @@ dsql_nod* MAKE_field(dsql_ctx* context, dsql_fld* field, dsql_nod* indices)
|
||||
dsql_nod* node = MAKE_node(nod_field, e_fld_count);
|
||||
node->nod_arg[e_fld_context] = (dsql_nod*) context;
|
||||
node->nod_arg[e_fld_field] = (dsql_nod*) field;
|
||||
if (field->fld_dimensions) {
|
||||
if (field->fld_dimensions)
|
||||
{
|
||||
if (indices) {
|
||||
node->nod_arg[e_fld_indices] = indices;
|
||||
MAKE_desc_from_field(&node->nod_desc, field);
|
||||
node->nod_desc.dsc_dtype =
|
||||
static_cast<UCHAR>(field->fld_element_dtype);
|
||||
node->nod_desc.dsc_dtype = static_cast<UCHAR>(field->fld_element_dtype);
|
||||
node->nod_desc.dsc_length = field->fld_element_length;
|
||||
/*
|
||||
node->nod_desc.dsc_scale = field->fld_scale;
|
||||
@ -1544,8 +1537,7 @@ dsql_nod* MAKE_field(dsql_ctx* context, dsql_fld* field, dsql_nod* indices)
|
||||
else {
|
||||
node->nod_desc.dsc_dtype = dtype_array;
|
||||
node->nod_desc.dsc_length = sizeof(ISC_QUAD);
|
||||
node->nod_desc.dsc_scale =
|
||||
static_cast<SCHAR>(field->fld_scale);
|
||||
node->nod_desc.dsc_scale = static_cast<SCHAR>(field->fld_scale);
|
||||
node->nod_desc.dsc_sub_type = field->fld_sub_type;
|
||||
}
|
||||
}
|
||||
@ -1565,8 +1557,7 @@ dsql_nod* MAKE_field(dsql_ctx* context, dsql_fld* field, dsql_nod* indices)
|
||||
}
|
||||
|
||||
// check if the field is a system domain and the type is CHAR/VARCHAR CHARACTER SET UNICODE_FSS
|
||||
if ((field->fld_flags & FLD_system) &&
|
||||
node->nod_desc.dsc_dtype <= dtype_varying &&
|
||||
if ((field->fld_flags & FLD_system) && node->nod_desc.dsc_dtype <= dtype_varying &&
|
||||
INTL_GET_CHARSET(&node->nod_desc) == CS_METADATA)
|
||||
{
|
||||
USHORT adjust = 0;
|
||||
@ -1931,7 +1922,8 @@ static void make_parameter_names(dsql_par* parameter, const dsql_nod* item)
|
||||
|
||||
const char* name_alias = NULL;
|
||||
|
||||
switch (item->nod_type) {
|
||||
switch (item->nod_type)
|
||||
{
|
||||
case nod_field:
|
||||
field = (dsql_fld*) item->nod_arg[e_fld_field];
|
||||
name_alias = field->fld_name.c_str();
|
||||
@ -1982,7 +1974,8 @@ static void make_parameter_names(dsql_par* parameter, const dsql_nod* item)
|
||||
map = (dsql_map*) map_node->nod_arg[e_map_map];
|
||||
map_node = map->map_node;
|
||||
}
|
||||
switch (map_node->nod_type) {
|
||||
switch (map_node->nod_type)
|
||||
{
|
||||
case nod_field:
|
||||
field = (dsql_fld*) map_node->nod_arg[e_fld_field];
|
||||
name_alias = field->fld_name.c_str();
|
||||
|
@ -569,16 +569,14 @@ dsql_nod* PASS1_node(CompiledStatement* statement, dsql_nod* input)
|
||||
{
|
||||
case nod_alias:
|
||||
node = MAKE_node(input->nod_type, e_alias_count);
|
||||
node->nod_arg[e_alias_value] = sub1 =
|
||||
PASS1_node(statement, input->nod_arg[e_alias_value]);
|
||||
node->nod_arg[e_alias_value] = sub1 = PASS1_node(statement, input->nod_arg[e_alias_value]);
|
||||
node->nod_arg[e_alias_alias] = input->nod_arg[e_alias_alias];
|
||||
node->nod_desc = sub1->nod_desc;
|
||||
return node;
|
||||
|
||||
case nod_cast:
|
||||
node = MAKE_node(input->nod_type, e_cast_count);
|
||||
node->nod_arg[e_cast_source] = sub1 =
|
||||
PASS1_node(statement, input->nod_arg[e_cast_source]);
|
||||
node->nod_arg[e_cast_source] = sub1 = PASS1_node(statement, input->nod_arg[e_cast_source]);
|
||||
node->nod_arg[e_cast_target] = input->nod_arg[e_cast_target];
|
||||
field = (dsql_fld*) node->nod_arg[e_cast_target];
|
||||
DEV_BLKCHK(field, dsql_type_fld);
|
||||
@ -933,8 +931,7 @@ dsql_nod* PASS1_node(CompiledStatement* statement, dsql_nod* input)
|
||||
node->nod_arg[1] = temp;
|
||||
dsql_nod* rse = PASS1_rse(statement, sub2, NULL);
|
||||
temp->nod_arg[e_via_rse] = rse;
|
||||
temp->nod_arg[e_via_value_1] =
|
||||
rse->nod_arg[e_rse_items]->nod_arg[0];
|
||||
temp->nod_arg[e_via_value_1] = rse->nod_arg[e_rse_items]->nod_arg[0];
|
||||
temp->nod_arg[e_via_value_2] = MAKE_node(nod_null, (int) 0);
|
||||
|
||||
// Try to force sub1 to be same type as sub2 eg: ? = (select ...) case
|
||||
@ -1020,8 +1017,7 @@ dsql_nod* PASS1_node(CompiledStatement* statement, dsql_nod* input)
|
||||
}
|
||||
else {
|
||||
// Scope level is needed to determine to which context COUNT(*) belongs.
|
||||
node->nod_arg[e_agg_function_scope_level] =
|
||||
(dsql_nod*)(IPTR) statement->req_scope_level;
|
||||
node->nod_arg[e_agg_function_scope_level] = (dsql_nod*)(IPTR) statement->req_scope_level;
|
||||
}
|
||||
return node;
|
||||
|
||||
@ -1050,8 +1046,7 @@ dsql_nod* PASS1_node(CompiledStatement* statement, dsql_nod* input)
|
||||
const dsql_nod* const ddl_node =
|
||||
(statement->req_type == REQ_DDL) ? statement->req_ddl_node : NULL;
|
||||
if (!ddl_node ||
|
||||
!(ddl_node->nod_type == nod_def_domain ||
|
||||
ddl_node->nod_type == nod_mod_domain))
|
||||
!(ddl_node->nod_type == nod_def_domain || ddl_node->nod_type == nod_mod_domain))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||
Arg::Gds(isc_dsql_domain_err));
|
||||
@ -1109,8 +1104,7 @@ dsql_nod* PASS1_node(CompiledStatement* statement, dsql_nod* input)
|
||||
case nod_named_param:
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_named_param_name] = input->nod_arg[e_named_param_name];
|
||||
node->nod_arg[e_named_param_expr] =
|
||||
PASS1_node(statement, input->nod_arg[e_named_param_expr]);
|
||||
node->nod_arg[e_named_param_expr] = PASS1_node(statement, input->nod_arg[e_named_param_expr]);
|
||||
return node;
|
||||
|
||||
default:
|
||||
@ -1386,8 +1380,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
for (const dsql_nod* const* const end2 =
|
||||
ptr2 + parameters->nod_count; ptr2 < end2; ptr2++)
|
||||
{
|
||||
const dsql_fld* field2 =
|
||||
(dsql_fld*) (*ptr2)->nod_arg[e_dfl_field];
|
||||
const dsql_fld* field2 = (dsql_fld*) (*ptr2)->nod_arg[e_dfl_field];
|
||||
DEV_BLKCHK(field2, dsql_type_fld);
|
||||
|
||||
if (field->fld_name == field2->fld_name)
|
||||
@ -1405,8 +1398,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
for (const dsql_nod* const* const end2 =
|
||||
ptr2 + parameters->nod_count; ptr2 < end2; ptr2++)
|
||||
{
|
||||
const dsql_fld* field2 =
|
||||
(dsql_fld*) (*ptr2)->nod_arg[e_dfl_field];
|
||||
const dsql_fld* field2 = (dsql_fld*) (*ptr2)->nod_arg[e_dfl_field];
|
||||
DEV_BLKCHK(field2, dsql_type_fld);
|
||||
|
||||
if (field->fld_name == field2->fld_name)
|
||||
@ -1520,8 +1512,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
Arg::Gds(isc_token_err) <<
|
||||
Arg::Gds(isc_random) << Arg::Str("RETURNING_VALUES"));
|
||||
}
|
||||
node->nod_arg[e_exe_outputs] =
|
||||
explode_outputs(statement, statement->req_procedure);
|
||||
node->nod_arg[e_exe_outputs] = explode_outputs(statement, statement->req_procedure);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1539,8 +1530,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_exe_blk_inputs] =
|
||||
pass1_node_psql(statement, input->nod_arg[e_exe_blk_inputs], false);
|
||||
node->nod_arg[e_exe_blk_outputs] =
|
||||
input->nod_arg[e_exe_blk_outputs];
|
||||
node->nod_arg[e_exe_blk_outputs] = input->nod_arg[e_exe_blk_outputs];
|
||||
|
||||
node->nod_arg[e_exe_blk_dcls] = input->nod_arg[e_exe_blk_dcls];
|
||||
node->nod_arg[e_exe_blk_body] = input->nod_arg[e_exe_blk_body];
|
||||
@ -1605,8 +1595,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
// but only if the command is FOR SELECT, otherwise we have singular SELECT
|
||||
statement->req_loop_level++;
|
||||
node->nod_arg[e_flp_label] = pass1_label(statement, input);
|
||||
node->nod_arg[e_flp_action] =
|
||||
PASS1_statement(statement, input->nod_arg[e_flp_action]);
|
||||
node->nod_arg[e_flp_action] = PASS1_statement(statement, input->nod_arg[e_flp_action]);
|
||||
statement->req_loop_level--;
|
||||
statement->req_labels.pop();
|
||||
}
|
||||
@ -1625,10 +1614,8 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
|
||||
case nod_if:
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_if_condition] =
|
||||
PASS1_node(statement, input->nod_arg[e_if_condition]);
|
||||
node->nod_arg[e_if_true] =
|
||||
PASS1_statement(statement, input->nod_arg[e_if_true]);
|
||||
node->nod_arg[e_if_condition] = PASS1_node(statement, input->nod_arg[e_if_condition]);
|
||||
node->nod_arg[e_if_true] = PASS1_statement(statement, input->nod_arg[e_if_true]);
|
||||
if (input->nod_arg[e_if_false])
|
||||
node->nod_arg[e_if_false] = PASS1_statement(statement, input->nod_arg[e_if_false]);
|
||||
else
|
||||
@ -1640,8 +1627,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
// if exception value is defined, pass value node
|
||||
if (input->nod_arg[e_xcps_msg])
|
||||
{
|
||||
node->nod_arg[e_xcps_msg] =
|
||||
PASS1_node(statement, input->nod_arg[e_xcps_msg]);
|
||||
node->nod_arg[e_xcps_msg] = PASS1_node(statement, input->nod_arg[e_xcps_msg]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1699,22 +1685,19 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
|
||||
case nod_post:
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_pst_event] =
|
||||
PASS1_node(statement, input->nod_arg[e_pst_event]);
|
||||
node->nod_arg[e_pst_event] = PASS1_node(statement, input->nod_arg[e_pst_event]);
|
||||
node->nod_arg[e_pst_argument] =
|
||||
PASS1_node(statement, input->nod_arg[e_pst_argument]);
|
||||
return node;
|
||||
|
||||
case nod_exec_sql:
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_exec_sql_stmnt] =
|
||||
PASS1_node(statement, input->nod_arg[e_exec_sql_stmnt]);
|
||||
node->nod_arg[e_exec_sql_stmnt] = PASS1_node(statement, input->nod_arg[e_exec_sql_stmnt]);
|
||||
return pass1_savepoint(statement, node);
|
||||
|
||||
case nod_exec_into:
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_exec_into_stmnt] =
|
||||
PASS1_node(statement, input->nod_arg[e_exec_into_stmnt]);
|
||||
node->nod_arg[e_exec_into_stmnt] = PASS1_node(statement, input->nod_arg[e_exec_into_stmnt]);
|
||||
if (input->nod_arg[e_exec_into_block]) {
|
||||
statement->req_loop_level++;
|
||||
node->nod_arg[e_exec_into_label] = pass1_label(statement, input);
|
||||
@ -1724,8 +1707,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
statement->req_labels.pop();
|
||||
}
|
||||
|
||||
node->nod_arg[e_exec_into_list] =
|
||||
PASS1_node(statement, input->nod_arg[e_exec_into_list]);
|
||||
node->nod_arg[e_exec_into_list] = PASS1_node(statement, input->nod_arg[e_exec_into_list]);
|
||||
return pass1_savepoint(statement, node);
|
||||
|
||||
case nod_exec_stmt:
|
||||
@ -1749,10 +1731,8 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
}
|
||||
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_exec_stmt_sql] =
|
||||
PASS1_node(statement, input->nod_arg[e_exec_stmt_sql]);
|
||||
node->nod_arg[e_exec_stmt_inputs] =
|
||||
PASS1_node(statement, input->nod_arg[e_exec_stmt_inputs]);
|
||||
node->nod_arg[e_exec_stmt_sql] = PASS1_node(statement, input->nod_arg[e_exec_stmt_sql]);
|
||||
node->nod_arg[e_exec_stmt_inputs] = PASS1_node(statement, input->nod_arg[e_exec_stmt_inputs]);
|
||||
|
||||
// check params names uniqueness, if present
|
||||
if (node->nod_arg[e_exec_stmt_inputs])
|
||||
@ -1776,8 +1756,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
}
|
||||
}
|
||||
|
||||
node->nod_arg[e_exec_stmt_outputs] =
|
||||
PASS1_node(statement, input->nod_arg[e_exec_stmt_outputs]);
|
||||
node->nod_arg[e_exec_stmt_outputs] = PASS1_node(statement, input->nod_arg[e_exec_stmt_outputs]);
|
||||
|
||||
if (input->nod_arg[e_exec_stmt_proc_block])
|
||||
{
|
||||
@ -1922,15 +1901,13 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
case nod_while:
|
||||
{
|
||||
node = MAKE_node(input->nod_type, input->nod_count);
|
||||
node->nod_arg[e_while_cond] =
|
||||
PASS1_node(statement, input->nod_arg[e_while_cond]);
|
||||
node->nod_arg[e_while_cond] = PASS1_node(statement, input->nod_arg[e_while_cond]);
|
||||
|
||||
// CVC: loop numbers should be incremented before analyzing the body
|
||||
// to preserve nesting <==> increasing level number
|
||||
statement->req_loop_level++;
|
||||
node->nod_arg[e_while_label] = pass1_label(statement, input);
|
||||
node->nod_arg[e_while_action] =
|
||||
PASS1_statement(statement, input->nod_arg[e_while_action]);
|
||||
node->nod_arg[e_while_action] = PASS1_statement(statement, input->nod_arg[e_while_action]);
|
||||
statement->req_loop_level--;
|
||||
statement->req_labels.pop();
|
||||
}
|
||||
@ -1980,16 +1957,14 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
|
||||
case nod_set_generator:
|
||||
node = MAKE_node(input->nod_type, e_gen_id_count);
|
||||
node->nod_arg[e_gen_id_value] =
|
||||
PASS1_node(statement, input->nod_arg[e_gen_id_value]);
|
||||
node->nod_arg[e_gen_id_value] = PASS1_node(statement, input->nod_arg[e_gen_id_value]);
|
||||
node->nod_arg[e_gen_id_name] = input->nod_arg[e_gen_id_name];
|
||||
statement->req_type = REQ_SET_GENERATOR;
|
||||
break;
|
||||
|
||||
case nod_set_generator2:
|
||||
node = MAKE_node(input->nod_type, e_gen_id_count);
|
||||
node->nod_arg[e_gen_id_value] =
|
||||
PASS1_node(statement, input->nod_arg[e_gen_id_value]);
|
||||
node->nod_arg[e_gen_id_value] = PASS1_node(statement, input->nod_arg[e_gen_id_value]);
|
||||
node->nod_arg[e_gen_id_name] = input->nod_arg[e_gen_id_name];
|
||||
statement->req_type = REQ_SET_GENERATOR;
|
||||
break;
|
||||
@ -2013,8 +1988,7 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
statement->req_context = &temp;
|
||||
const dsql_nod* select = input->nod_arg[e_cur_rse];
|
||||
input->nod_arg[e_cur_rse] =
|
||||
PASS1_rse(statement, select->nod_arg[e_select_expr],
|
||||
select->nod_arg[e_select_lock]);
|
||||
PASS1_rse(statement, select->nod_arg[e_select_expr], select->nod_arg[e_select_lock]);
|
||||
statement->req_context->clear();
|
||||
statement->req_context = base_context;
|
||||
// assign number and store in the statement stack
|
||||
@ -2053,13 +2027,11 @@ dsql_nod* PASS1_statement(CompiledStatement* statement, dsql_nod* input)
|
||||
NOD_CURSOR_EXPLICIT, true);
|
||||
// process a seek node, if exists
|
||||
if (input->nod_arg[e_cur_stmt_seek]) {
|
||||
input->nod_arg[e_cur_stmt_seek] =
|
||||
PASS1_node(statement, input->nod_arg[e_cur_stmt_seek]);
|
||||
input->nod_arg[e_cur_stmt_seek] = PASS1_node(statement, input->nod_arg[e_cur_stmt_seek]);
|
||||
}
|
||||
// process an assignment node, if exists
|
||||
if (input->nod_arg[e_cur_stmt_into]) {
|
||||
input->nod_arg[e_cur_stmt_into] =
|
||||
PASS1_node(statement, input->nod_arg[e_cur_stmt_into]);
|
||||
input->nod_arg[e_cur_stmt_into] = PASS1_node(statement, input->nod_arg[e_cur_stmt_into]);
|
||||
}
|
||||
return input;
|
||||
|
||||
@ -2204,8 +2176,7 @@ static bool aggregate_found2(const CompiledStatement* statement, const dsql_nod*
|
||||
|
||||
case nod_field:
|
||||
{
|
||||
const dsql_ctx* lcontext =
|
||||
reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fld_context]);
|
||||
const dsql_ctx* lcontext = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fld_context]);
|
||||
if (*deepest_level < lcontext->ctx_scope_level) {
|
||||
*deepest_level = lcontext->ctx_scope_level;
|
||||
}
|
||||
@ -2655,8 +2626,7 @@ static dsql_nod* explode_outputs( CompiledStatement* statement, const dsql_prc*
|
||||
dsql_nod* p_node = MAKE_node(nod_parameter, e_par_count);
|
||||
*ptr = p_node;
|
||||
p_node->nod_count = 0;
|
||||
dsql_par* parameter =
|
||||
MAKE_parameter(statement->req_receive, true, true, 0, NULL);
|
||||
dsql_par* parameter = MAKE_parameter(statement->req_receive, true, true, 0, NULL);
|
||||
p_node->nod_arg[e_par_index] = (dsql_nod*) (IPTR) parameter->par_index;
|
||||
p_node->nod_arg[e_par_parameter] = (dsql_nod*) parameter;
|
||||
MAKE_desc_from_field(¶meter->par_desc, field);
|
||||
@ -3473,8 +3443,7 @@ static bool node_match(const dsql_nod* node1, const dsql_nod* node2,
|
||||
(node1->nod_type == nod_agg_average) ||
|
||||
(node1->nod_type == nod_agg_list))
|
||||
{
|
||||
if ((node1->nod_flags & NOD_AGG_DISTINCT) !=
|
||||
(node2->nod_flags & NOD_AGG_DISTINCT))
|
||||
if ((node1->nod_flags & NOD_AGG_DISTINCT) != (node2->nod_flags & NOD_AGG_DISTINCT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3506,8 +3475,7 @@ static bool node_match(const dsql_nod* node1, const dsql_nod* node2,
|
||||
const dsql_nod* const* ptr1 = node1->nod_arg;
|
||||
const dsql_nod* const* ptr2 = node2->nod_arg;
|
||||
|
||||
for (const dsql_nod* const* const end = ptr1 + node1->nod_count;
|
||||
ptr1 < end; ptr1++, ptr2++)
|
||||
for (const dsql_nod* const* const end = ptr1 + node1->nod_count; ptr1 < end; ptr1++, ptr2++)
|
||||
{
|
||||
if (!node_match(*ptr1, *ptr2, ignore_map_cast)) {
|
||||
return false;
|
||||
@ -3676,13 +3644,11 @@ static void pass1_blob( CompiledStatement* statement, dsql_nod* input)
|
||||
|
||||
// Create a parameter for the blob segment
|
||||
|
||||
dsql_par* parameter =
|
||||
MAKE_parameter(blob->blb_segment_msg, true, true, 0, NULL);
|
||||
dsql_par* parameter = MAKE_parameter(blob->blb_segment_msg, true, true, 0, NULL);
|
||||
blob->blb_segment = parameter;
|
||||
parameter->par_desc.dsc_dtype = dtype_text;
|
||||
parameter->par_desc.dsc_ttype() = ttype_binary;
|
||||
parameter->par_desc.dsc_length =
|
||||
((dsql_fld*) field->nod_arg[e_fld_field])->fld_seg_length;
|
||||
parameter->par_desc.dsc_length = ((dsql_fld*) field->nod_arg[e_fld_field])->fld_seg_length;
|
||||
DEV_BLKCHK(field->nod_arg[e_fld_field], dsql_type_fld);
|
||||
|
||||
/* The Null indicator is used to pass back the segment length,
|
||||
@ -3696,8 +3662,7 @@ static void pass1_blob( CompiledStatement* statement, dsql_nod* input)
|
||||
|
||||
dsql_msg* temp_msg = (input->nod_type == nod_get_segment) ?
|
||||
blob->blb_open_in_msg : blob->blb_open_out_msg;
|
||||
blob->blb_blob_id = parameter =
|
||||
MAKE_parameter(temp_msg, true, true, 0, NULL);
|
||||
blob->blb_blob_id = parameter = MAKE_parameter(temp_msg, true, true, 0, NULL);
|
||||
MAKE_desc(statement, ¶meter->par_desc, field, NULL);
|
||||
parameter->par_desc.dsc_dtype = dtype_quad;
|
||||
parameter->par_desc.dsc_scale = 0;
|
||||
@ -3877,8 +3842,7 @@ static dsql_nod* pass1_constant( CompiledStatement* statement, dsql_nod* input)
|
||||
if (string && string->str_charset)
|
||||
{
|
||||
const dsql_intlsym* resolved =
|
||||
METD_get_charset(statement, strlen(string->str_charset),
|
||||
string->str_charset);
|
||||
METD_get_charset(statement, strlen(string->str_charset), string->str_charset);
|
||||
if (!resolved)
|
||||
{
|
||||
// character set name is not defined
|
||||
@ -4177,8 +4141,7 @@ static dsql_nod* pass1_cursor_reference( CompiledStatement* statement,
|
||||
temp->nod_arg[e_par_parameter] = (dsql_nod*) parameter;
|
||||
parameter->par_desc = rv_source->par_desc;
|
||||
|
||||
rse->nod_arg[e_rse_boolean] =
|
||||
compose(rse->nod_arg[e_rse_boolean], node, nod_and);
|
||||
rse->nod_arg[e_rse_boolean] = compose(rse->nod_arg[e_rse_boolean], node, nod_and);
|
||||
}
|
||||
|
||||
return rse;
|
||||
@ -4310,10 +4273,8 @@ static dsql_nod* pass1_delete( CompiledStatement* statement, dsql_nod* input)
|
||||
dsql_nod* relation = input->nod_arg[e_del_relation];
|
||||
if (cursor && statement->isPsql()) {
|
||||
dsql_nod* anode = MAKE_node(nod_erase_current, e_erc_count);
|
||||
anode->nod_arg[e_erc_context] =
|
||||
(dsql_nod*) pass1_cursor_context(statement, cursor, relation);
|
||||
anode->nod_arg[e_erc_return] =
|
||||
process_returning(statement, input->nod_arg[e_del_return]);
|
||||
anode->nod_arg[e_erc_context] = (dsql_nod*) pass1_cursor_context(statement, cursor, relation);
|
||||
anode->nod_arg[e_erc_return] = process_returning(statement, input->nod_arg[e_del_return]);
|
||||
return anode;
|
||||
}
|
||||
|
||||
@ -4811,8 +4772,7 @@ static dsql_nod* pass1_derived_table(CompiledStatement* statement, dsql_nod* inp
|
||||
dsql_nod* const select_expr = input->nod_arg[e_derived_table_rse];
|
||||
dsql_nod* query = select_expr->nod_arg[e_sel_query_spec];
|
||||
dsql_nod* rse = NULL;
|
||||
const bool isRecursive =
|
||||
(query->nod_type == nod_list) && (query->nod_flags & NOD_UNION_RECURSIVE);
|
||||
const bool isRecursive = (query->nod_type == nod_list) && (query->nod_flags & NOD_UNION_RECURSIVE);
|
||||
USHORT recursive_map_ctx = 0;
|
||||
|
||||
if (isRecursive)
|
||||
@ -4970,8 +4930,7 @@ static dsql_nod* pass1_derived_table(CompiledStatement* statement, dsql_nod* inp
|
||||
// Auto-create dummy column name for pass1_any()
|
||||
if (ignoreColumnChecks && (select_item->nod_type != nod_derived_field)) {
|
||||
// Make new derived field node
|
||||
dsql_nod* derived_field =
|
||||
MAKE_node(nod_derived_field, e_derived_field_count);
|
||||
dsql_nod* derived_field = MAKE_node(nod_derived_field, e_derived_field_count);
|
||||
derived_field->nod_arg[e_derived_field_value] = select_item;
|
||||
|
||||
// Construct dummy fieldname
|
||||
@ -5001,8 +4960,7 @@ static dsql_nod* pass1_derived_table(CompiledStatement* statement, dsql_nod* inp
|
||||
|
||||
if (select_item->nod_type == nod_derived_field)
|
||||
{
|
||||
select_item->nod_arg[e_derived_field_context] =
|
||||
reinterpret_cast<dsql_nod*>(context);
|
||||
select_item->nod_arg[e_derived_field_context] = reinterpret_cast<dsql_nod*>(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5762,10 +5720,9 @@ static bool pass1_found_aggregate(const dsql_nod* node, USHORT check_scope_level
|
||||
|
||||
case nod_map:
|
||||
{
|
||||
const dsql_map* map =
|
||||
reinterpret_cast<dsql_map*>(node->nod_arg[e_map_map]);
|
||||
found |= pass1_found_aggregate(map->map_node,
|
||||
check_scope_level, match_type, current_scope_level_equal);
|
||||
const dsql_map* map = reinterpret_cast<dsql_map*>(node->nod_arg[e_map_map]);
|
||||
found |= pass1_found_aggregate(map->map_node, check_scope_level, match_type,
|
||||
current_scope_level_equal);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5953,10 +5910,10 @@ static bool pass1_found_field(const dsql_nod* node, USHORT check_scope_level,
|
||||
{
|
||||
// This is a "virtual" field
|
||||
*field = true;
|
||||
const USHORT df_scope_level =
|
||||
(USHORT)(U_IPTR) node->nod_arg[e_derived_field_scope];
|
||||
const USHORT df_scope_level = (USHORT)(U_IPTR) node->nod_arg[e_derived_field_scope];
|
||||
|
||||
switch (match_type) {
|
||||
switch (match_type)
|
||||
{
|
||||
case FIELD_MATCH_TYPE_EQUAL:
|
||||
return (df_scope_level == check_scope_level);
|
||||
|
||||
@ -6000,10 +5957,8 @@ static bool pass1_found_field(const dsql_nod* node, USHORT check_scope_level,
|
||||
|
||||
case nod_map:
|
||||
{
|
||||
const dsql_map* map =
|
||||
reinterpret_cast<dsql_map*>(node->nod_arg[e_map_map]);
|
||||
found |= pass1_found_field(map->map_node, check_scope_level,
|
||||
match_type, field);
|
||||
const dsql_map* map = reinterpret_cast<dsql_map*>(node->nod_arg[e_map_map]);
|
||||
found |= pass1_found_field(map->map_node, check_scope_level, match_type, field);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -6420,8 +6375,7 @@ static dsql_nod* pass1_insert( CompiledStatement* statement, dsql_nod* input, bo
|
||||
// marks it with CTX_null so all fields be resolved to NULL constant.
|
||||
dsql_ctx* old_context = FB_NEW(statement->req_pool) dsql_ctx(statement->req_pool);
|
||||
*old_context = *context;
|
||||
old_context->ctx_alias = old_context->ctx_internal_alias =
|
||||
MAKE_cstring(OLD_CONTEXT)->str_data;
|
||||
old_context->ctx_alias = old_context->ctx_internal_alias = MAKE_cstring(OLD_CONTEXT)->str_data;
|
||||
old_context->ctx_flags |= CTX_system | CTX_null | CTX_returning;
|
||||
statement->req_context->push(old_context);
|
||||
|
||||
@ -6429,8 +6383,7 @@ static dsql_nod* pass1_insert( CompiledStatement* statement, dsql_nod* input, bo
|
||||
dsql_ctx* new_context = FB_NEW(statement->req_pool) dsql_ctx(statement->req_pool);
|
||||
*new_context = *context;
|
||||
new_context->ctx_scope_level = ++statement->req_scope_level;
|
||||
new_context->ctx_alias = new_context->ctx_internal_alias =
|
||||
MAKE_cstring(NEW_CONTEXT)->str_data;
|
||||
new_context->ctx_alias = new_context->ctx_internal_alias = MAKE_cstring(NEW_CONTEXT)->str_data;
|
||||
new_context->ctx_flags |= CTX_system | CTX_returning;
|
||||
statement->req_context->push(new_context);
|
||||
}
|
||||
@ -6483,33 +6436,25 @@ static dsql_nod* pass1_join(CompiledStatement* statement, dsql_nod* input)
|
||||
|
||||
switch (node->nod_arg[e_join_type]->nod_type) {
|
||||
case nod_join_inner:
|
||||
node->nod_arg[e_join_left_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
node->nod_arg[e_join_rght_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
node->nod_arg[e_join_left_rel] = PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
node->nod_arg[e_join_rght_rel] = PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
break;
|
||||
case nod_join_left:
|
||||
node->nod_arg[e_join_left_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
node->nod_arg[e_join_left_rel] = PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
statement->req_in_outer_join++;
|
||||
node->nod_arg[e_join_rght_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
node->nod_arg[e_join_rght_rel] = PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
statement->req_in_outer_join--;
|
||||
break;
|
||||
case nod_join_right:
|
||||
statement->req_in_outer_join++;
|
||||
node->nod_arg[e_join_left_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
node->nod_arg[e_join_left_rel] = PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
statement->req_in_outer_join--;
|
||||
node->nod_arg[e_join_rght_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
node->nod_arg[e_join_rght_rel] = PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
break;
|
||||
case nod_join_full:
|
||||
statement->req_in_outer_join++;
|
||||
node->nod_arg[e_join_left_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
node->nod_arg[e_join_rght_rel] =
|
||||
PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
node->nod_arg[e_join_left_rel] = PASS1_node(statement, input->nod_arg[e_join_left_rel]);
|
||||
node->nod_arg[e_join_rght_rel] = PASS1_node(statement, input->nod_arg[e_join_rght_rel]);
|
||||
statement->req_in_outer_join--;
|
||||
break;
|
||||
|
||||
@ -7732,8 +7677,7 @@ static dsql_nod* pass1_returning(CompiledStatement* statement, const dsql_nod* i
|
||||
dsql_nod* const source = pass1_node_psql(statement, input->nod_arg[e_ret_source], false);
|
||||
|
||||
statement->req_flags |= REQ_returning_into;
|
||||
dsql_nod* const target =
|
||||
PASS1_node(statement, input->nod_arg[e_ret_target]);
|
||||
dsql_nod* const target = PASS1_node(statement, input->nod_arg[e_ret_target]);
|
||||
statement->req_flags &= ~REQ_returning_into;
|
||||
|
||||
if (!statement->isPsql() && target)
|
||||
@ -7792,8 +7736,7 @@ static dsql_nod* pass1_returning(CompiledStatement* statement, const dsql_nod* i
|
||||
for (const dsql_nod* const* const end = ptr + node->nod_count;
|
||||
ptr < end; src++, ptr++)
|
||||
{
|
||||
dsql_par* parameter =
|
||||
MAKE_parameter(statement->req_receive, true, true, 0, *src);
|
||||
dsql_par* parameter = MAKE_parameter(statement->req_receive, true, true, 0, *src);
|
||||
parameter->par_node = *src;
|
||||
MAKE_desc(statement, ¶meter->par_desc, *src, NULL);
|
||||
parameter->par_desc.dsc_flags |= DSC_nullable;
|
||||
@ -8731,8 +8674,7 @@ static dsql_nod* pass1_union( CompiledStatement* statement, dsql_nod* input,
|
||||
|
||||
// set up the rse node for the union.
|
||||
dsql_nod* union_rse = MAKE_node(nod_rse, e_rse_count);
|
||||
dsql_nod* union_node = union_rse->nod_arg[e_rse_streams] =
|
||||
MAKE_node(nod_union, input->nod_count);
|
||||
dsql_nod* union_node = union_rse->nod_arg[e_rse_streams] = MAKE_node(nod_union, input->nod_count);
|
||||
union_node->nod_flags = input->nod_flags;
|
||||
|
||||
// generate a context for the union itself.
|
||||
@ -9188,13 +9130,11 @@ static dsql_nod* pass1_update(CompiledStatement* statement, dsql_nod* input, boo
|
||||
*ptr = pass1_node_psql(statement, *ptr, false);
|
||||
}
|
||||
|
||||
anode->nod_arg[e_mdc_return] =
|
||||
process_returning(statement, input->nod_arg[e_upd_return]);
|
||||
anode->nod_arg[e_mdc_return] = process_returning(statement, input->nod_arg[e_upd_return]);
|
||||
|
||||
statement->req_context->pop();
|
||||
// Recreate list of assignments
|
||||
anode->nod_arg[e_mdc_statement] = list =
|
||||
MAKE_node(nod_list, list->nod_count);
|
||||
anode->nod_arg[e_mdc_statement] = list = MAKE_node(nod_list, list->nod_count);
|
||||
for (int i = 0; i < list->nod_count; ++i)
|
||||
{
|
||||
dsql_nod* assign = MAKE_node(nod_assign, e_asgn_count);
|
||||
@ -9298,8 +9238,7 @@ static dsql_nod* pass1_update(CompiledStatement* statement, dsql_nod* input, boo
|
||||
// Process the RETURNING with the stack (NEW, (modify, OLD)),
|
||||
// so unqualified or qualified by NEW or the table name fields be
|
||||
// resolved to the changed record.
|
||||
node->nod_arg[e_mod_return] =
|
||||
process_returning(statement, input->nod_arg[e_upd_return]);
|
||||
node->nod_arg[e_mod_return] = process_returning(statement, input->nod_arg[e_upd_return]);
|
||||
|
||||
// restore the stack with only the RSE context
|
||||
--statement->req_scope_level;
|
||||
@ -9377,8 +9316,7 @@ static dsql_nod* pass1_update_or_insert(CompiledStatement* statement, dsql_nod*
|
||||
if (!statement->isPsql())
|
||||
statement->req_flags |= REQ_dsql_upd_or_ins;
|
||||
|
||||
const dsql_str* relation_name =
|
||||
(dsql_str*) input->nod_arg[e_upi_relation]->nod_arg[e_rpn_name];
|
||||
const dsql_str* relation_name = (dsql_str*) input->nod_arg[e_upi_relation]->nod_arg[e_rpn_name];
|
||||
const dsql_str* base_name = relation_name;
|
||||
|
||||
dsql_nod* values = input->nod_arg[e_upi_values];
|
||||
@ -9410,8 +9348,7 @@ static dsql_nod* pass1_update_or_insert(CompiledStatement* statement, dsql_nod*
|
||||
|
||||
if ((relation->rel_flags & REL_view) && !input->nod_arg[e_upi_matching])
|
||||
{
|
||||
dsql_rel* base_rel =
|
||||
METD_get_view_base(statement, relation_name->str_data, view_fields);
|
||||
dsql_rel* base_rel = METD_get_view_base(statement, relation_name->str_data, view_fields);
|
||||
|
||||
// get the base table name if there is only one
|
||||
if (base_rel)
|
||||
@ -9500,14 +9437,15 @@ static dsql_nod* pass1_update_or_insert(CompiledStatement* statement, dsql_nod*
|
||||
DEV_BLKCHK(*matching_ptr, dsql_type_nod);
|
||||
fb_assert((*matching_ptr)->nod_type == nod_field_name);
|
||||
|
||||
if (Firebird::MetaName(((dsql_str*)
|
||||
(*matching_ptr)->nod_arg[e_fln_name])->str_data) ==
|
||||
field_name)
|
||||
const Firebird::MetaName
|
||||
testfield(((dsql_str*)(*matching_ptr)->nod_arg[e_fln_name])->str_data);
|
||||
|
||||
if (testfield == field_name)
|
||||
{
|
||||
++match_count;
|
||||
|
||||
dsql_nod*& expr = insert->nod_arg[e_sto_statement]->nod_arg[
|
||||
field_ptr - fields->nod_arg]->nod_arg[0];
|
||||
const size_t fieldpos = field_ptr - fields->nod_arg;
|
||||
dsql_nod*& expr = insert->nod_arg[e_sto_statement]->nod_arg[fieldpos]->nod_arg[0];
|
||||
dsql_nod* var = pass1_hidden_variable(statement, expr);
|
||||
|
||||
if (var)
|
||||
@ -9701,8 +9639,7 @@ static dsql_nod* pass1_variable( CompiledStatement* statement, dsql_nod* input)
|
||||
{
|
||||
//position = 0;
|
||||
dsql_nod** ptr = var_nodes->nod_arg;
|
||||
for (const dsql_nod* const* const end =
|
||||
ptr + var_nodes->nod_count; ptr < end; ptr++) //, position++)
|
||||
for (const dsql_nod* const* const end = ptr + var_nodes->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_nod* var_node = *ptr;
|
||||
const dsql_var* variable = (dsql_var*) var_node->nod_arg[e_var_variable];
|
||||
@ -9720,8 +9657,7 @@ static dsql_nod* pass1_variable( CompiledStatement* statement, dsql_nod* input)
|
||||
{
|
||||
//position = 0;
|
||||
dsql_nod** ptr = var_nodes->nod_arg;
|
||||
for (const dsql_nod* const* const end =
|
||||
ptr + var_nodes->nod_count; ptr < end; ptr++) //, position++)
|
||||
for (const dsql_nod* const* const end = ptr + var_nodes->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_nod* var_node = *ptr;
|
||||
const dsql_var* variable = (dsql_var*) var_node->nod_arg[e_var_variable];
|
||||
@ -9744,8 +9680,7 @@ static dsql_nod* pass1_variable( CompiledStatement* statement, dsql_nod* input)
|
||||
// try to resolve variable name against local variables
|
||||
//position = 0;
|
||||
dsql_nod** ptr = var_nodes->nod_arg;
|
||||
for (const dsql_nod* const* const end =
|
||||
ptr + var_nodes->nod_count; ptr < end; ptr++) //, position++)
|
||||
for (const dsql_nod* const* const end = ptr + var_nodes->nod_count; ptr < end; ptr++)
|
||||
{
|
||||
dsql_nod* var_node = *ptr;
|
||||
if (var_node->nod_type == nod_variable)
|
||||
@ -9884,8 +9819,7 @@ static dsql_nod* remap_field(CompiledStatement* statement, dsql_nod* field,
|
||||
// If we got a field from a derived table we should not remap anything
|
||||
// deeper in the alias, but this "virtual" field should be mapped to
|
||||
// the given context (of course only if we're in the same scope-level).
|
||||
const USHORT lscope_level =
|
||||
(USHORT)(U_IPTR)field->nod_arg[e_derived_field_scope];
|
||||
const USHORT lscope_level = (USHORT)(U_IPTR) field->nod_arg[e_derived_field_scope];
|
||||
if (lscope_level == context->ctx_scope_level) {
|
||||
return post_map(field, context);
|
||||
}
|
||||
@ -9893,15 +9827,14 @@ static dsql_nod* remap_field(CompiledStatement* statement, dsql_nod* field,
|
||||
if (context->ctx_scope_level < lscope_level) {
|
||||
field->nod_arg[e_derived_field_value] =
|
||||
remap_field(statement, field->nod_arg[e_derived_field_value],
|
||||
context, current_level);
|
||||
context, current_level);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
case nod_field:
|
||||
{
|
||||
const dsql_ctx* lcontext =
|
||||
reinterpret_cast<dsql_ctx*>(field->nod_arg[e_fld_context]);
|
||||
const dsql_ctx* lcontext = reinterpret_cast<dsql_ctx*>(field->nod_arg[e_fld_context]);
|
||||
if (lcontext->ctx_scope_level == context->ctx_scope_level) {
|
||||
return post_map(field, context);
|
||||
}
|
||||
@ -9911,12 +9844,11 @@ static dsql_nod* remap_field(CompiledStatement* statement, dsql_nod* field,
|
||||
|
||||
case nod_map:
|
||||
{
|
||||
const dsql_ctx* lcontext =
|
||||
reinterpret_cast<dsql_ctx*>(field->nod_arg[e_map_context]);
|
||||
const dsql_ctx* lcontext = reinterpret_cast<dsql_ctx*>(field->nod_arg[e_map_context]);
|
||||
if (lcontext->ctx_scope_level != context->ctx_scope_level) {
|
||||
dsql_map* lmap = reinterpret_cast<dsql_map*>(field->nod_arg[e_map_map]);
|
||||
lmap->map_node = remap_field(statement, lmap->map_node, context,
|
||||
lcontext->ctx_scope_level);
|
||||
lcontext->ctx_scope_level);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
@ -9940,16 +9872,16 @@ static dsql_nod* remap_field(CompiledStatement* statement, dsql_nod* field,
|
||||
|
||||
if (field->nod_count) {
|
||||
field->nod_arg[e_agg_function_expression] =
|
||||
remap_field(statement, field->nod_arg[e_agg_function_expression],
|
||||
context, current_level);
|
||||
remap_field(statement, field->nod_arg[e_agg_function_expression],
|
||||
context, current_level);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
if (field->nod_count) {
|
||||
field->nod_arg[e_agg_function_expression] =
|
||||
remap_field(statement, field->nod_arg[e_agg_function_expression],
|
||||
context, current_level);
|
||||
remap_field(statement, field->nod_arg[e_agg_function_expression],
|
||||
context, current_level);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
@ -10079,8 +10011,7 @@ static dsql_nod* remap_field(CompiledStatement* statement, dsql_nod* field,
|
||||
|
||||
case nod_relation:
|
||||
{
|
||||
dsql_ctx* lrelation_context =
|
||||
reinterpret_cast<dsql_ctx*>(field->nod_arg[e_rel_context]);
|
||||
dsql_ctx* lrelation_context = reinterpret_cast<dsql_ctx*>(field->nod_arg[e_rel_context]);
|
||||
// Check if relation is a procedure
|
||||
if (lrelation_context->ctx_procedure) {
|
||||
// Remap the input parameters
|
||||
@ -10473,8 +10404,7 @@ static bool set_parameter_type(CompiledStatement* statement, dsql_nod* in_node,
|
||||
dsql_nod* par_node = in_node->nod_arg[e_cast_source];
|
||||
dsql_fld* field = (dsql_fld*) in_node->nod_arg[e_cast_target];
|
||||
if (par_node->nod_type == nod_parameter) {
|
||||
dsql_par* parameter =
|
||||
(dsql_par*) par_node->nod_arg[e_par_parameter];
|
||||
dsql_par* parameter = (dsql_par*) par_node->nod_arg[e_par_parameter];
|
||||
DEV_BLKCHK(parameter, dsql_type_par);
|
||||
parameter->par_desc = par_node->nod_desc;
|
||||
parameter->par_node = par_node;
|
||||
|
Loading…
Reference in New Issue
Block a user