8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Implementation of CORE-1235: NATURAL JOIN and JOIN...USING

This commit is contained in:
asfernandes 2007-04-29 19:04:26 +00:00
parent 41fb347a95
commit c5cf6ea6b8
15 changed files with 433 additions and 93 deletions

View File

@ -1562,6 +1562,10 @@ C --
PARAMETER (GDS__dsql_cte_miss_nonrecursive = 336397233)
INTEGER*4 GDS__dsql_cte_nested_with
PARAMETER (GDS__dsql_cte_nested_with = 336397234)
INTEGER*4 GDS__dsql_col_more_than_once_using
PARAMETER (GDS__dsql_col_more_than_once_using = 336397235)
INTEGER*4 GDS__dsql_unsupp_feature_dialect
PARAMETER (GDS__dsql_unsupp_feature_dialect = 336397236)
INTEGER*4 GDS__gsec_cant_open_db
PARAMETER (GDS__gsec_cant_open_db = 336723983)
INTEGER*4 GDS__gsec_switches_error

View File

@ -788,6 +788,8 @@ const
gds_dsql_cte_union_all = 336397232;
gds_dsql_cte_miss_nonrecursive = 336397233;
gds_dsql_cte_nested_with = 336397234;
gds_dsql_col_more_than_once_using = 336397235;
gds_dsql_unsupp_feature_dialect = 336397236;
gds_gsec_cant_open_db = 336723983;
gds_gsec_switches_error = 336723984;
gds_gsec_no_op_spec = 336723985;

View File

@ -21,6 +21,7 @@
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
* Adriano dos Santos Fernandes
*/
#ifndef CLASSES_ARRAY_H
@ -303,6 +304,13 @@ public:
return highBound != this->count &&
!Cmp::greaterThan(KeyOfValue::generate(this, this->data[lowBound]), item);
}
bool exist(const Key& item) const
{
size_t pos; // ignored
return find(item, pos);
}
size_t add(const Value& item) {
size_t pos;
find(KeyOfValue::generate(this, item), pos);

View File

@ -45,6 +45,7 @@ enum blk_t {
dsql_type_prc,
dsql_type_intlsym,
dsql_type_vec,
dsql_type_imp_join,
dsql_type_MAX
};

View File

@ -28,6 +28,7 @@
* 2002.10.29 Nickolay Samofatov: Added support for savepoints
* 2004.01.16 Vlad Horsun: added support for default parameters and
* EXECUTE BLOCK statement
* Adriano dos Santos Fernandes
*/
#ifndef DSQL_DSQL_H
@ -36,6 +37,8 @@
#include "../jrd/common.h"
#include "../dsql/all.h"
#include "../common/classes/array.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/MetaName.h"
#include "../common/classes/stack.h"
#define REQUESTER
#include "../jrd/val.h" // Get rid of duplicated FUN_T enum.
@ -566,13 +569,23 @@ public:
dsql_tra* tra_next; //!< Next open transaction
};
//! Implicit (NATURAL and USING) joins
class ImplicitJoin : public pool_alloc<dsql_type_imp_join>
{
public:
dsql_nod* value;
dsql_ctx* visibleInContext;
};
//! Context block used to create an instance of a relation reference
class dsql_ctx : public pool_alloc<dsql_type_ctx>
{
public:
dsql_ctx(MemoryPool &p)
: ctx_childs_derived_table(p) {}
: ctx_childs_derived_table(p),
ctx_imp_join(p)
{
}
dsql_req* ctx_request; //!< Parent request
dsql_rel* ctx_relation; //!< Relation for context
@ -587,6 +600,8 @@ public:
USHORT ctx_scope_level; //!< Subquery level within this request
USHORT ctx_flags; //!< Various flag values
DsqlContextStack ctx_childs_derived_table; //!< Childs derived table context
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::MetaName, ImplicitJoin*> > > ctx_imp_join; // Map of USING fieldname to ImplicitJoin
dsql_ctx& operator=(dsql_ctx& v)
{
@ -605,6 +620,8 @@ public:
return *this;
}
bool getImplicitJoinField(const TEXT* name, dsql_nod*& node);
};
// Flag values for ctx_flags

View File

@ -781,6 +781,7 @@ enum node_args {
e_alias_value = 0, // nod_alias
e_alias_alias,
e_alias_imp_join,
e_alias_count,
e_rct_name = 0, // nod_rel_constraint
@ -984,7 +985,8 @@ enum node_args {
e_derived_field_value = 0, // Contains the source expression
e_derived_field_name, // Name for derived table field
e_derived_field_scope, // Scope-level
e_derived_field_count = 4,
e_derived_field_context, // context of derived table
e_derived_field_count,
e_cur_stmt_id = 0,
e_cur_stmt_seek,

View File

@ -224,7 +224,7 @@ static dsql_nod* pass1_dbkey(dsql_req*, dsql_nod*);
static dsql_nod* pass1_delete(dsql_req*, dsql_nod*, bool);
static dsql_nod* pass1_derived_table(dsql_req*, dsql_nod*, bool, dsql_str*);
static dsql_nod* pass1_expand_select_list(dsql_req*, dsql_nod*, dsql_nod*);
static void pass1_expand_select_node(dsql_req*, dsql_nod*, DsqlNodStack&);
static void pass1_expand_select_node(dsql_req*, dsql_nod*, DsqlNodStack&, bool);
static dsql_nod* pass1_field(dsql_req*, dsql_nod*, const bool, dsql_nod*);
static bool pass1_found_aggregate(const dsql_nod*, USHORT, USHORT, bool);
static bool pass1_found_field(const dsql_nod*, USHORT, USHORT, bool*);
@ -233,7 +233,7 @@ static dsql_nod* pass1_group_by_list(dsql_req*, dsql_nod*, dsql_nod*);
static dsql_nod* pass1_insert(dsql_req*, dsql_nod*, bool, bool);
static dsql_nod* pass1_join(dsql_req*, dsql_nod*, bool);
static dsql_nod* pass1_label(dsql_req*, dsql_nod*);
static dsql_nod* pass1_lookup_alias(dsql_req*, const dsql_str*, dsql_nod*);
static dsql_nod* pass1_lookup_alias(dsql_req*, const dsql_str*, dsql_nod*, bool);
static dsql_nod* pass1_make_derived_field(dsql_req*, tsql*, dsql_nod*);
static dsql_nod* pass1_merge(dsql_req*, dsql_nod*, bool);
static dsql_nod* pass1_not(dsql_req*, const dsql_nod*, bool, bool);
@ -261,6 +261,8 @@ static dsql_nod* remap_field(dsql_req*, dsql_nod*, dsql_ctx*, USHORT);
static dsql_nod* remap_fields(dsql_req*, dsql_nod*, dsql_ctx*);
static void remap_streams_to_parent_context(dsql_nod*, dsql_ctx*);
static dsql_fld* resolve_context(dsql_req*, const dsql_str*, dsql_ctx*, bool);
static dsql_nod* resolve_using_field(dsql_req* request, dsql_str* name, DsqlNodStack& stack,
const dsql_nod* flawedNode, const TEXT* side, dsql_ctx*& ctx);
static dsql_nod* resolve_variable_name(const dsql_nod* var_nodes, const dsql_str* var_name);
static bool set_parameter_type(dsql_req*, dsql_nod*, dsql_nod*, bool);
static void set_parameters_name(dsql_nod*, const dsql_nod*);
@ -4686,9 +4688,17 @@ static dsql_nod* pass1_derived_table(dsql_req* request, dsql_nod* input, bool pr
int count;
// Check if all root select-items have a derived field else show a message.
for (count = 0; count < rse->nod_arg[e_rse_items]->nod_count; count++) {
const dsql_nod* select_item = rse->nod_arg[e_rse_items]->nod_arg[count];
if (select_item->nod_type != nod_derived_field) {
for (count = 0; count < rse->nod_arg[e_rse_items]->nod_count; count++)
{
dsql_nod* select_item = rse->nod_arg[e_rse_items]->nod_arg[count];
if (select_item->nod_type == nod_derived_field)
{
select_item->nod_arg[e_derived_field_context] =
reinterpret_cast<dsql_nod*>(context);
}
else
{
// no column name specified for column number %d in derived table %s
ERRD_post(isc_sqlerr, isc_arg_number, (SLONG) - 104,
@ -4790,7 +4800,7 @@ static dsql_nod* pass1_expand_select_list(dsql_req* request, dsql_nod* list,
for (const dsql_nod* const* const end = ptr + list->nod_count;
ptr < end; ptr++)
{
pass1_expand_select_node(request, *ptr, stack);
pass1_expand_select_node(request, *ptr, stack, true);
}
dsql_nod* node = MAKE_list(stack);
return node;
@ -4808,17 +4818,20 @@ static dsql_nod* pass1_expand_select_list(dsql_req* request, dsql_nod* list,
@param stack
**/
static void pass1_expand_select_node(dsql_req* request, dsql_nod* node, DsqlNodStack& stack)
static void pass1_expand_select_node(dsql_req* request, dsql_nod* node, DsqlNodStack& stack,
bool hide_using)
{
DEV_BLKCHK(node, dsql_type_nod);
if (node->nod_type == nod_join) {
pass1_expand_select_node(request, node->nod_arg[e_join_left_rel], stack);
pass1_expand_select_node(request, node->nod_arg[e_join_rght_rel], stack);
pass1_expand_select_node(request, node->nod_arg[e_join_left_rel], stack, true);
pass1_expand_select_node(request, node->nod_arg[e_join_rght_rel], stack, true);
}
else if (node->nod_type == nod_derived_table) {
// AB: Derived table support
tsql* tdsql = DSQL_get_thread_data();
dsql_ctx* context = (dsql_ctx*) node->nod_arg[e_derived_table_context];
DEV_BLKCHK(context, dsql_type_ctx);
dsql_nod* sub_items = node->nod_arg[e_derived_table_rse]->nod_arg[e_rse_items];
dsql_nod** ptr = sub_items->nod_arg;
for (const dsql_nod* const* const end = ptr + sub_items->nod_count;
@ -4833,7 +4846,13 @@ static void pass1_expand_select_node(dsql_req* request, dsql_nod* node, DsqlNodS
isc_arg_gds, isc_dsql_command_err,
isc_arg_gds, isc_dsql_derived_alias_select, 0);
}
stack.push(select_item);
if (!hide_using ||
context->getImplicitJoinField(reinterpret_cast<dsql_str*>(
select_item->nod_arg[e_derived_field_name])->str_data, select_item))
{
stack.push(select_item);
}
}
}
else if (node->nod_type == nod_relation) {
@ -4846,8 +4865,14 @@ static void pass1_expand_select_node(dsql_req* request, dsql_nod* node, DsqlNodS
field = field->fld_next)
{
DEV_BLKCHK(field, dsql_type_fld);
dsql_nod* select_item = MAKE_field(context, field, 0);
stack.push(select_item);
dsql_nod* select_item = NULL;
if (!hide_using || context->getImplicitJoinField(field->fld_name, select_item))
{
if (!select_item)
select_item = MAKE_field(context, field, 0);
stack.push(select_item);
}
}
}
else if (procedure = context->ctx_procedure) {
@ -4855,15 +4880,21 @@ static void pass1_expand_select_node(dsql_req* request, dsql_nod* node, DsqlNodS
field = field->fld_next)
{
DEV_BLKCHK(field, dsql_type_fld);
dsql_nod* select_item = MAKE_field(context, field, 0);
stack.push(select_item);
dsql_nod* select_item = NULL;
if (!hide_using || context->getImplicitJoinField(field->fld_name, select_item))
{
if (!select_item)
select_item = MAKE_field(context, field, 0);
stack.push(select_item);
}
}
}
}
else if (node->nod_type == nod_field_name) {
dsql_nod* select_item = pass1_field(request, node, true, NULL);
// The node could be a relation so call recursively.
pass1_expand_select_node(request, select_item, stack);
pass1_expand_select_node(request, select_item, stack, false);
}
else {
stack.push(node);
@ -4979,7 +5010,7 @@ static dsql_nod* pass1_field( dsql_req* request, dsql_nod* input,
// AB: Check first against the select list for matching column.
// When no matches at all are found we go on with our
// normal way of field name lookup.
dsql_nod* node = pass1_lookup_alias(request, name, select_list);
dsql_nod* node = pass1_lookup_alias(request, name, select_list, true);
if (node) {
return node;
}
@ -5035,8 +5066,23 @@ static dsql_nod* pass1_field( dsql_req* request, dsql_nod* input,
}
}
for (; field; field = field->fld_next) {
if (!strcmp(reinterpret_cast<const char*>(name->str_data), field->fld_name)) {
dsql_nod* using_field = NULL;
for (; field; field = field->fld_next)
{
if (!strcmp(reinterpret_cast<const char*>(name->str_data), field->fld_name))
{
if (!qualifier)
{
if (!context->getImplicitJoinField(field->fld_name, using_field))
{
field = NULL;
break;
}
else if (using_field)
field = NULL;
}
ambiguous_ctx_stack.push(context);
break;
}
@ -5050,11 +5096,11 @@ static dsql_nod* pass1_field( dsql_req* request, dsql_nod* input,
break;
}
if (field) {
if (field || using_field) {
// Intercept any reference to a field with datatype that
// did not exist prior to V6 and post an error
if (request->req_client_dialect <= SQL_DIALECT_V5 &&
if (request->req_client_dialect <= SQL_DIALECT_V5 && field &&
(field->fld_dtype == dtype_sql_date ||
field->fld_dtype == dtype_sql_time ||
field->fld_dtype == dtype_int64))
@ -5086,8 +5132,10 @@ static dsql_nod* pass1_field( dsql_req* request, dsql_nod* input,
if (context->ctx_flags & CTX_null)
node = MAKE_node(nod_null, 0);
else
else if (field)
node = MAKE_field(context, field, indices);
else
node = list ? using_field : PASS1_node(request, using_field, false);
}
}
else if (is_derived_table) {
@ -6076,12 +6124,199 @@ static dsql_nod* pass1_join(dsql_req* request, dsql_nod* input, bool proc_flag)
dsql_nod* boolean = input->nod_arg[e_join_boolean];
if (boolean && (boolean->nod_type == nod_flag || boolean->nod_type == nod_list))
{
// Process NATURAL JOIN or USING clause
ERRD_post(isc_wish_list, 0);
if (request->req_client_dialect < SQL_DIALECT_V6)
{
ERRD_post(
isc_sqlerr, isc_arg_number, (SLONG) -901,
isc_arg_gds, isc_dsql_unsupp_feature_dialect,
isc_arg_number, request->req_client_dialect,
0);
}
DsqlNodStack leftStack, rightStack;
if (boolean->nod_type == nod_flag) // NATURAL JOIN
{
StrArray leftNames(request->req_pool);
DsqlNodStack matched;
pass1_expand_select_node(request, node->nod_arg[e_join_left_rel], leftStack, true);
pass1_expand_select_node(request, node->nod_arg[e_join_rght_rel], rightStack, true);
// verify columns that exist in both sides
for (int i = 0; i < 2; ++i)
{
for (DsqlNodStack::const_iterator j(i == 0 ? leftStack : rightStack); j.hasData(); ++j)
{
const TEXT* name = NULL;
dsql_nod* item = j.object();
switch (item->nod_type)
{
case nod_alias:
name = reinterpret_cast<dsql_str*>(item->nod_arg[e_alias_alias])->str_data;
break;
case nod_field:
name = reinterpret_cast<dsql_fld*>(item->nod_arg[e_fld_field])->fld_name;
break;
case nod_derived_field:
name = reinterpret_cast<dsql_str*>(item->nod_arg[e_derived_field_name])->str_data;
break;
default:
break;
}
if (name)
{
if (i == 0) // left
leftNames.add(name);
else // right
{
if (leftNames.exist(name))
{
item = MAKE_node(nod_field_name, e_fln_count);
item->nod_arg[e_fln_name] =
reinterpret_cast<dsql_nod*>(MAKE_cstring(name));
matched.push(item);
}
}
}
}
}
if (matched.getCount() == 0)
{
// There is no match. Transform to CROSS JOIN.
node->nod_arg[e_join_type]->nod_type = nod_join_inner;
boolean = NULL;
}
else
boolean = MAKE_list(matched); // Transform to USING
}
if (boolean && boolean->nod_type == nod_list) // JOIN ... USING
{
dsql_nod* newBoolean = NULL;
StrArray usedColumns(request->req_pool);
for (int i = 0; i < boolean->nod_count; ++i)
{
dsql_nod* field = boolean->nod_arg[i];
dsql_str* fldName = reinterpret_cast<dsql_str*>(field->nod_arg[e_fln_name]);
// verify if the column was already used
if (usedColumns.exist(fldName->str_data))
{
ERRD_post(
isc_sqlerr, isc_arg_number, (SLONG) -104,
isc_arg_gds, isc_dsql_col_more_than_once_using,
isc_arg_string, fldName->str_data,
0);
}
else
usedColumns.add(fldName->str_data);
dsql_ctx* leftCtx = NULL;
dsql_ctx* rightCtx = NULL;
// clear the stacks for the next pass
leftStack.clear();
rightStack.clear();
// get the column names from both sides
pass1_expand_select_node(request, node->nod_arg[e_join_left_rel], leftStack, true);
pass1_expand_select_node(request, node->nod_arg[e_join_rght_rel], rightStack, true);
// create the boolean
dsql_nod* eqlNode = MAKE_node(nod_eql, 2);
eqlNode->nod_arg[0] = resolve_using_field(request,
fldName, leftStack, field, "left", leftCtx);
eqlNode->nod_arg[1] = resolve_using_field(request,
fldName, rightStack, field, "right", rightCtx);
fb_assert(leftCtx);
fb_assert(rightCtx);
// We should hide the (unqualified) column in one side
ImplicitJoin* impJoinLeft;
if (!leftCtx->ctx_imp_join.get(fldName->str_data, impJoinLeft))
{
impJoinLeft = FB_NEW(request->req_pool) ImplicitJoin();
impJoinLeft->value = eqlNode->nod_arg[0];
impJoinLeft->visibleInContext = leftCtx;
}
else
fb_assert(impJoinLeft->visibleInContext == leftCtx);
ImplicitJoin* impJoinRight;
if (!rightCtx->ctx_imp_join.get(fldName->str_data, impJoinRight))
{
impJoinRight = FB_NEW(request->req_pool) ImplicitJoin();
impJoinRight->value = eqlNode->nod_arg[1];
}
else
fb_assert(impJoinRight->visibleInContext == rightCtx);
// create the COALESCE
DsqlNodStack stack;
dsql_nod* temp;
if ((temp = impJoinLeft->value)->nod_type == nod_alias)
temp = temp->nod_arg[e_alias_value];
if (temp->nod_type == nod_coalesce)
{
pass1_put_args_on_stack(request, temp->nod_arg[0], stack, false);
pass1_put_args_on_stack(request, temp->nod_arg[1], stack, false);
}
else
pass1_put_args_on_stack(request, temp, stack, false);
if ((temp = impJoinRight->value)->nod_type == nod_alias)
temp = temp->nod_arg[e_alias_value];
if (temp->nod_type == nod_coalesce)
{
pass1_put_args_on_stack(request, temp->nod_arg[0], stack, false);
pass1_put_args_on_stack(request, temp->nod_arg[1], stack, false);
}
else
pass1_put_args_on_stack(request, temp, stack, false);
dsql_nod* coalesce = MAKE_node(nod_coalesce, 2);
coalesce->nod_arg[0] = stack.pop();
coalesce->nod_arg[1] = MAKE_list(stack);
impJoinLeft->value = MAKE_node(nod_alias, e_alias_count);
impJoinLeft->value->nod_arg[e_alias_value] = coalesce;
impJoinLeft->value->nod_arg[e_alias_alias] = reinterpret_cast<dsql_nod*>(fldName);
impJoinLeft->value->nod_arg[e_alias_imp_join] = reinterpret_cast<dsql_nod*>(impJoinLeft);
impJoinRight->visibleInContext = NULL;
// both sides should refer to the same ImplicitJoin
leftCtx->ctx_imp_join.put(fldName->str_data, impJoinLeft);
rightCtx->ctx_imp_join.put(fldName->str_data, impJoinLeft);
if (newBoolean)
{
temp = MAKE_node(nod_and, 2);
temp->nod_arg[0] = newBoolean;
temp->nod_arg[1] = eqlNode;
newBoolean = temp;
}
else
newBoolean = eqlNode;
}
boolean = newBoolean;
}
else if (boolean)
fb_assert(false);
}
node->nod_arg[e_join_boolean] =
PASS1_node(request, input->nod_arg[e_join_boolean], proc_flag);
node->nod_arg[e_join_boolean] = PASS1_node(request, boolean, proc_flag);
return node;
}
@ -6207,7 +6442,8 @@ static dsql_nod* pass1_label(dsql_req* request, dsql_nod* input)
@param selectList
**/
static dsql_nod* pass1_lookup_alias(dsql_req* request, const dsql_str* name, dsql_nod* selectList)
static dsql_nod* pass1_lookup_alias(dsql_req* request, const dsql_str* name, dsql_nod* selectList,
bool process)
{
dsql_nod* returnNode = NULL;
dsql_nod** ptr = selectList->nod_arg;
@ -6220,7 +6456,7 @@ static dsql_nod* pass1_lookup_alias(dsql_req* request, const dsql_str* name, dsq
{
dsql_str* alias = (dsql_str*) node->nod_arg[e_alias_alias];
if (!strcmp(alias->str_data, name->str_data)) {
matchingNode = PASS1_node(request, node, false);
matchingNode = node;
}
}
break;
@ -6229,7 +6465,7 @@ static dsql_nod* pass1_lookup_alias(dsql_req* request, const dsql_str* name, dsq
{
dsql_fld* field = (dsql_fld*) node->nod_arg[e_fld_field];
if (!strcmp(field->fld_name, name->str_data)) {
matchingNode = PASS1_node(request, node, false);
matchingNode = node;
}
}
break;
@ -6238,7 +6474,7 @@ static dsql_nod* pass1_lookup_alias(dsql_req* request, const dsql_str* name, dsq
{
dsql_str* alias = (dsql_str*) node->nod_arg[e_derived_field_name];
if (!strcmp(alias->str_data, name->str_data)) {
matchingNode = PASS1_node(request, node, false);
matchingNode = node;
}
}
break;
@ -6247,6 +6483,9 @@ static dsql_nod* pass1_lookup_alias(dsql_req* request, const dsql_str* name, dsq
break;
}
if (matchingNode) {
if (process)
matchingNode = PASS1_node(request, matchingNode, false);
if (returnNode) {
// There was already a node matched, thus raise ambiguous field name error.
TEXT buffer1[256];
@ -9567,6 +9806,36 @@ static dsql_fld* resolve_context( dsql_req* request, const dsql_str* qualifier,
}
// Resolve a field for JOIN USING purposes
static dsql_nod* resolve_using_field(dsql_req* request, dsql_str* name, DsqlNodStack& stack,
const dsql_nod* flawedNode, const TEXT* side, dsql_ctx*& ctx)
{
dsql_nod* list = MAKE_list(stack);
dsql_nod* node = pass1_lookup_alias(request, name, list, false);
if (!node)
{
Firebird::string qualifier;
qualifier.printf("<%s side of USING>", side);
field_unknown(qualifier.c_str(), name->str_data, flawedNode);
}
if (node->nod_type == nod_derived_field)
ctx = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_derived_field_context]);
else if (node->nod_type == nod_field)
ctx = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fln_context]);
else if (node->nod_type == nod_alias)
{
fb_assert(node->nod_count >= (int) e_alias_imp_join - 1);
ctx = reinterpret_cast<ImplicitJoin*>(node->nod_arg[e_alias_imp_join])->visibleInContext;
}
else
fb_assert(false);
return node;
}
/**
set_parameter_type
@ -9938,3 +10207,24 @@ void dsql_req::clearCTEs()
req_ctes.clear();
req_cte_aliases.clear();
}
// Returns false for hidden fields and true for non-hidden.
// For non-hidden, change "node" if the field is part of an
// implicit join.
bool dsql_ctx::getImplicitJoinField(const TEXT* name, dsql_nod*& node)
{
ImplicitJoin* impJoin;
if (ctx_imp_join.get(name, impJoin))
{
if (impJoin->visibleInContext == this)
{
node = impJoin->value;
return true;
}
else
return false;
}
return true;
}

View File

@ -777,6 +777,8 @@ static const struct {
{"dsql_cte_union_all", 336397232},
{"dsql_cte_miss_nonrecursive", 336397233},
{"dsql_cte_nested_with", 336397234},
{"dsql_col_more_than_once_using", 336397235},
{"dsql_unsupp_feature_dialect", 336397236},
{"gsec_cant_open_db", 336723983},
{"gsec_switches_error", 336723984},
{"gsec_no_op_spec", 336723985},

View File

@ -810,6 +810,8 @@ const ISC_LONG isc_dsql_cte_wrong_clause = 336397231L;
const ISC_LONG isc_dsql_cte_union_all = 336397232L;
const ISC_LONG isc_dsql_cte_miss_nonrecursive = 336397233L;
const ISC_LONG isc_dsql_cte_nested_with = 336397234L;
const ISC_LONG isc_dsql_col_more_than_once_using = 336397235L;
const ISC_LONG isc_dsql_unsupp_feature_dialect = 336397236L;
const ISC_LONG isc_gsec_cant_open_db = 336723983L;
const ISC_LONG isc_gsec_switches_error = 336723984L;
const ISC_LONG isc_gsec_no_op_spec = 336723985L;
@ -869,7 +871,7 @@ const ISC_LONG isc_gstat_unexpected_eof = 336920580L;
const ISC_LONG isc_gstat_open_err = 336920605L;
const ISC_LONG isc_gstat_read_err = 336920606L;
const ISC_LONG isc_gstat_sysmemex = 336920607L;
const ISC_LONG isc_err_max = 814;
const ISC_LONG isc_err_max = 816;
#else /* c definitions */
@ -1649,6 +1651,8 @@ const ISC_LONG isc_err_max = 814;
#define isc_dsql_cte_union_all 336397232L
#define isc_dsql_cte_miss_nonrecursive 336397233L
#define isc_dsql_cte_nested_with 336397234L
#define isc_dsql_col_more_than_once_using 336397235L
#define isc_dsql_unsupp_feature_dialect 336397236L
#define isc_gsec_cant_open_db 336723983L
#define isc_gsec_switches_error 336723984L
#define isc_gsec_no_op_spec 336723985L
@ -1708,7 +1712,7 @@ const ISC_LONG isc_err_max = 814;
#define isc_gstat_open_err 336920605L
#define isc_gstat_read_err 336920606L
#define isc_gstat_sysmemex 336920607L
#define isc_err_max 814
#define isc_err_max 816
#endif

View File

@ -777,64 +777,66 @@ static const struct {
{336397232, "Recursive members of CTE (@1) must be linked with another members via UNION ALL"}, /* 753, dsql_cte_union_all */
{336397233, "Non-recursive member is missing in CTE '@1'"}, /* 754, dsql_cte_miss_nonrecursive */
{336397234, "WITH clause can't be nested"}, /* 755, dsql_cte_nested_with */
{336723983, "unable to open database"}, /* 756, gsec_cant_open_db */
{336723984, "error in switch specifications"}, /* 757, gsec_switches_error */
{336723985, "no operation specified"}, /* 758, gsec_no_op_spec */
{336723986, "no user name specified"}, /* 759, gsec_no_usr_name */
{336723987, "add record error"}, /* 760, gsec_err_add */
{336723988, "modify record error"}, /* 761, gsec_err_modify */
{336723989, "find/modify record error"}, /* 762, gsec_err_find_mod */
{336723990, "record not found for user: @1"}, /* 763, gsec_err_rec_not_found */
{336723991, "delete record error"}, /* 764, gsec_err_delete */
{336723992, "find/delete record error"}, /* 765, gsec_err_find_del */
{336723996, "find/display record error"}, /* 766, gsec_err_find_disp */
{336723997, "invalid parameter, no switch defined"}, /* 767, gsec_inv_param */
{336723998, "operation already specified"}, /* 768, gsec_op_specified */
{336723999, "password already specified"}, /* 769, gsec_pw_specified */
{336724000, "uid already specified"}, /* 770, gsec_uid_specified */
{336724001, "gid already specified"}, /* 771, gsec_gid_specified */
{336724002, "project already specified"}, /* 772, gsec_proj_specified */
{336724003, "organization already specified"}, /* 773, gsec_org_specified */
{336724004, "first name already specified"}, /* 774, gsec_fname_specified */
{336724005, "middle name already specified"}, /* 775, gsec_mname_specified */
{336724006, "last name already specified"}, /* 776, gsec_lname_specified */
{336724008, "invalid switch specified"}, /* 777, gsec_inv_switch */
{336724009, "ambiguous switch specified"}, /* 778, gsec_amb_switch */
{336724010, "no operation specified for parameters"}, /* 779, gsec_no_op_specified */
{336724011, "no parameters allowed for this operation"}, /* 780, gsec_params_not_allowed */
{336724012, "incompatible switches specified"}, /* 781, gsec_incompat_switch */
{336724044, "Invalid user name (maximum 31 bytes allowed)"}, /* 782, gsec_inv_username */
{336724045, "Warning - maximum 8 significant bytes of password used"}, /* 783, gsec_inv_pw_length */
{336724046, "database already specified"}, /* 784, gsec_db_specified */
{336724047, "database administrator name already specified"}, /* 785, gsec_db_admin_specified */
{336724048, "database administrator password already specified"}, /* 786, gsec_db_admin_pw_specified */
{336724049, "SQL role name already specified"}, /* 787, gsec_sql_role_specified */
{336789504, "The license file does not exist or could not be opened for read"}, /* 788, license_no_file */
{336789523, "operation already specified"}, /* 789, license_op_specified */
{336789524, "no operation specified"}, /* 790, license_op_missing */
{336789525, "invalid switch"}, /* 791, license_inv_switch */
{336789526, "invalid switch combination"}, /* 792, license_inv_switch_combo */
{336789527, "illegal operation/switch combination"}, /* 793, license_inv_op_combo */
{336789528, "ambiguous switch"}, /* 794, license_amb_switch */
{336789529, "invalid parameter, no switch specified"}, /* 795, license_inv_parameter */
{336789530, "switch does not take any parameter"}, /* 796, license_param_specified */
{336789531, "switch requires a parameter"}, /* 797, license_param_req */
{336789532, "syntax error in command line"}, /* 798, license_syntx_error */
{336789534, "The certificate was not added. A duplicate ID exists in the license file."}, /* 799, license_dup_id */
{336789535, "The certificate was not added. Invalid certificate ID / Key combination."}, /* 800, license_inv_id_key */
{336789536, "The certificate was not removed. The key does not exist or corresponds to a temporary evaluation license."}, /* 801, license_err_remove */
{336789537, "An error occurred updating the license file. Operation cancelled."}, /* 802, license_err_update */
{336789538, "The certificate could not be validated based on the information given. Please recheck the ID and key information."}, /* 803, license_err_convert */
{336789539, "Operation failed. An unknown error occurred."}, /* 804, license_err_unk */
{336789540, "Add license operation failed, KEY: @1 ID: @2"}, /* 805, license_svc_err_add */
{336789541, "Remove license operation failed, KEY: @1"}, /* 806, license_svc_err_remove */
{336789563, "The evaluation license has already been used on this server. You need to purchase a non-evaluation license."}, /* 807, license_eval_exists */
{336920577, "found unknown switch"}, /* 808, gstat_unknown_switch */
{336920578, "please retry, giving a database name"}, /* 809, gstat_retry */
{336920579, "Wrong ODS version, expected @1, encountered @2"}, /* 810, gstat_wrong_ods */
{336920580, "Unexpected end of database file."}, /* 811, gstat_unexpected_eof */
{336920605, "Can't open database file @1"}, /* 812, gstat_open_err */
{336920606, "Can't read a database page"}, /* 813, gstat_read_err */
{336920607, "System memory exhausted"}, /* 814, gstat_sysmemex */
{336397235, "column @1 appears more than once in USING clause"}, /* 756, dsql_col_more_than_once_using */
{336397236, "feature is not supported in dialect @1"}, /* 757, dsql_unsupp_feature_dialect */
{336723983, "unable to open database"}, /* 758, gsec_cant_open_db */
{336723984, "error in switch specifications"}, /* 759, gsec_switches_error */
{336723985, "no operation specified"}, /* 760, gsec_no_op_spec */
{336723986, "no user name specified"}, /* 761, gsec_no_usr_name */
{336723987, "add record error"}, /* 762, gsec_err_add */
{336723988, "modify record error"}, /* 763, gsec_err_modify */
{336723989, "find/modify record error"}, /* 764, gsec_err_find_mod */
{336723990, "record not found for user: @1"}, /* 765, gsec_err_rec_not_found */
{336723991, "delete record error"}, /* 766, gsec_err_delete */
{336723992, "find/delete record error"}, /* 767, gsec_err_find_del */
{336723996, "find/display record error"}, /* 768, gsec_err_find_disp */
{336723997, "invalid parameter, no switch defined"}, /* 769, gsec_inv_param */
{336723998, "operation already specified"}, /* 770, gsec_op_specified */
{336723999, "password already specified"}, /* 771, gsec_pw_specified */
{336724000, "uid already specified"}, /* 772, gsec_uid_specified */
{336724001, "gid already specified"}, /* 773, gsec_gid_specified */
{336724002, "project already specified"}, /* 774, gsec_proj_specified */
{336724003, "organization already specified"}, /* 775, gsec_org_specified */
{336724004, "first name already specified"}, /* 776, gsec_fname_specified */
{336724005, "middle name already specified"}, /* 777, gsec_mname_specified */
{336724006, "last name already specified"}, /* 778, gsec_lname_specified */
{336724008, "invalid switch specified"}, /* 779, gsec_inv_switch */
{336724009, "ambiguous switch specified"}, /* 780, gsec_amb_switch */
{336724010, "no operation specified for parameters"}, /* 781, gsec_no_op_specified */
{336724011, "no parameters allowed for this operation"}, /* 782, gsec_params_not_allowed */
{336724012, "incompatible switches specified"}, /* 783, gsec_incompat_switch */
{336724044, "Invalid user name (maximum 31 bytes allowed)"}, /* 784, gsec_inv_username */
{336724045, "Warning - maximum 8 significant bytes of password used"}, /* 785, gsec_inv_pw_length */
{336724046, "database already specified"}, /* 786, gsec_db_specified */
{336724047, "database administrator name already specified"}, /* 787, gsec_db_admin_specified */
{336724048, "database administrator password already specified"}, /* 788, gsec_db_admin_pw_specified */
{336724049, "SQL role name already specified"}, /* 789, gsec_sql_role_specified */
{336789504, "The license file does not exist or could not be opened for read"}, /* 790, license_no_file */
{336789523, "operation already specified"}, /* 791, license_op_specified */
{336789524, "no operation specified"}, /* 792, license_op_missing */
{336789525, "invalid switch"}, /* 793, license_inv_switch */
{336789526, "invalid switch combination"}, /* 794, license_inv_switch_combo */
{336789527, "illegal operation/switch combination"}, /* 795, license_inv_op_combo */
{336789528, "ambiguous switch"}, /* 796, license_amb_switch */
{336789529, "invalid parameter, no switch specified"}, /* 797, license_inv_parameter */
{336789530, "switch does not take any parameter"}, /* 798, license_param_specified */
{336789531, "switch requires a parameter"}, /* 799, license_param_req */
{336789532, "syntax error in command line"}, /* 800, license_syntx_error */
{336789534, "The certificate was not added. A duplicate ID exists in the license file."}, /* 801, license_dup_id */
{336789535, "The certificate was not added. Invalid certificate ID / Key combination."}, /* 802, license_inv_id_key */
{336789536, "The certificate was not removed. The key does not exist or corresponds to a temporary evaluation license."}, /* 803, license_err_remove */
{336789537, "An error occurred updating the license file. Operation cancelled."}, /* 804, license_err_update */
{336789538, "The certificate could not be validated based on the information given. Please recheck the ID and key information."}, /* 805, license_err_convert */
{336789539, "Operation failed. An unknown error occurred."}, /* 806, license_err_unk */
{336789540, "Add license operation failed, KEY: @1 ID: @2"}, /* 807, license_svc_err_add */
{336789541, "Remove license operation failed, KEY: @1"}, /* 808, license_svc_err_remove */
{336789563, "The evaluation license has already been used on this server. You need to purchase a non-evaluation license."}, /* 809, license_eval_exists */
{336920577, "found unknown switch"}, /* 810, gstat_unknown_switch */
{336920578, "please retry, giving a database name"}, /* 811, gstat_retry */
{336920579, "Wrong ODS version, expected @1, encountered @2"}, /* 812, gstat_wrong_ods */
{336920580, "Unexpected end of database file."}, /* 813, gstat_unexpected_eof */
{336920605, "Can't open database file @1"}, /* 814, gstat_open_err */
{336920606, "Can't read a database page"}, /* 815, gstat_read_err */
{336920607, "System memory exhausted"}, /* 816, gstat_sysmemex */
{0, NULL}
};

View File

@ -833,4 +833,6 @@ static SLONG user_codes[] = {
0,
0,
0,
0,
0,
};

View File

@ -776,6 +776,8 @@ static const struct {
{336397232, -104}, /* 944 dsql_cte_union_all */
{336397233, -104}, /* 945 dsql_cte_miss_nonrecursive */
{336397234, -104}, /* 946 dsql_cte_nested_with */
{336397235, -104}, /* 947 dsql_col_more_than_once_using */
{336397236, -901}, /* 948 dsql_unsupp_feature_dialect */
{336723983, -901}, /* 15 gsec_cant_open_db */
{336723984, -901}, /* 16 gsec_switches_error */
{336723985, -901}, /* 17 gsec_no_op_spec */

View File

@ -18,7 +18,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
('1996-11-07 13:39:40', 'INSTALL', 10, 1)
('1996-11-07 13:38:41', 'TEST', 11, 4)
('2007-04-07 13:11:00', 'GBAK', 12, 296)
('2006-11-05 11:20:00', 'SQLERR', 13, 947)
('2007-04-29 14:17:00', 'SQLERR', 13, 949)
('1996-11-07 13:38:42', 'SQLWARN', 14, 613)
('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307)
--

View File

@ -2526,6 +2526,8 @@ constrained - no 2 table rows can have duplicate column values', NULL, NULL);
('dsql_cte_nested_with', 'dsql_req::addCTEs', 'dsql.cpp', NULL, 13, 946, NULL, 'WITH clause can''t be nested', NULL, NULL);
-- Do not change the arguments of the previous SQLERR messages.
-- Write the new SQLERR messages here.
('dsql_col_more_than_once_using', 'pass1_join', 'dsql.cpp', NULL, 13, 947, NULL, 'column @1 appears more than once in USING clause', NULL, NULL);
('dsql_unsupp_feature_dialect', NULL, NULL, NULL, 13, 948, NULL, 'feature is not supported in dialect @1', NULL, NULL);
-- SQLWARN
(NULL, NULL, NULL, NULL, 14, 100, NULL, 'Row not found for fetch, update or delete, or the result of a query is an empty table.', NULL, NULL);
(NULL, NULL, NULL, NULL, 14, 101, NULL, 'segment buffer length shorter than expected', NULL, NULL);

View File

@ -762,6 +762,8 @@ COMMIT WORK;
(-104, NULL, NULL, 13, 944, NULL, 'dsql_cte_union_all', NULL, NULL)
(-104, NULL, NULL, 13, 945, NULL, 'dsql_cte_miss_nonrecursive', NULL, NULL)
(-104, NULL, NULL, 13, 946, NULL, 'dsql_cte_nested_with', NULL, NULL)
(-104, NULL, NULL, 13, 947, NULL, 'dsql_col_more_than_once_using', NULL, NULL)
(-901, NULL, NULL, 13, 948, NULL, 'dsql_unsupp_feature_dialect', NULL, NULL)
-- GSEC
(-901, NULL, NULL, 18, 15, NULL, 'gsec_cant_open_db', NULL, NULL)
(-901, NULL, NULL, 18, 16, NULL, 'gsec_switches_error', NULL, NULL)