~ubuntu-branches/ubuntu/karmic/firebird2.1/karmic

« back to all changes in this revision

Viewing changes to src/jrd/par.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Damyan Ivanov
  • Date: 2008-05-26 23:59:25 UTC
  • Revision ID: james.westby@ubuntu.com-20080526235925-2pnqj6nxpppoeaer
Tags: upstream-2.1.0.17798-0.ds2
ImportĀ upstreamĀ versionĀ 2.1.0.17798-0.ds2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      PROGRAM:        JRD Access Method
 
3
 *      MODULE:         par.cpp
 
4
 *      DESCRIPTION:    BLR Parser
 
5
 *
 
6
 * The contents of this file are subject to the Interbase Public
 
7
 * License Version 1.0 (the "License"); you may not use this file
 
8
 * except in compliance with the License. You may obtain a copy
 
9
 * of the License at http://www.Inprise.com/IPL.html
 
10
 *
 
11
 * Software distributed under the License is distributed on an
 
12
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 
13
 * or implied. See the License for the specific language governing
 
14
 * rights and limitations under the License.
 
15
 *
 
16
 * The Original Code was created by Inprise Corporation
 
17
 * and its predecessors. Portions created by Inprise Corporation are
 
18
 * Copyright (C) Inprise Corporation.
 
19
 *
 
20
 * All Rights Reserved.
 
21
 * Contributor(s): ______________________________________.
 
22
 *
 
23
 * 27-May-2001 Claudio Valderrama: par_plan() no longer uppercases
 
24
 *                      an index's name before doing a lookup of such index.
 
25
 * 2001.07.28: Added parse code for blr_skip to support LIMIT.
 
26
 * 2002.09.28 Dmitry Yemanov: Reworked internal_info stuff, enhanced
 
27
 *                            exception handling in SPs/triggers,
 
28
 *                            implemented ROWS_AFFECTED system variable
 
29
 * 2002.10.21 Nickolay Samofatov: Added support for explicit pessimistic locks
 
30
 * 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "MPEXL" port
 
31
 * 2002.10.29 Mike Nordell - Fixed breakage.
 
32
 * 2002.10.29 Nickolay Samofatov: Added support for savepoints
 
33
 * 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
 
34
 * 2003.10.05 Dmitry Yemanov: Added support for explicit cursors in PSQL
 
35
 * 2004.01.16 Vlad Horsun: Added support for default parameters 
 
36
 * Adriano dos Santos Fernandes
 
37
 */
 
38
 
 
39
#include "firebird.h"
 
40
#include <stdio.h>
 
41
#include <string.h>
 
42
#include "../jrd/common.h"
 
43
#include <stdarg.h>
 
44
#include "../jrd/jrd.h"
 
45
#include "../jrd/ibase.h"
 
46
#include "../jrd/ini.h"
 
47
#include "../jrd/val.h"
 
48
#include "../jrd/align.h"
 
49
#include "../jrd/exe.h"
 
50
#include "../jrd/lls.h"
 
51
#include "../jrd/rse.h" // for MAX_STREAMS
 
52
 
 
53
#include "../jrd/scl.h"
 
54
#include "../jrd/all.h"
 
55
#include "../jrd/req.h"
 
56
#include "../jrd/blb.h"
 
57
#include "../jrd/intl.h"
 
58
#include "../jrd/met.h"
 
59
#include "../jrd/cmp_proto.h"
 
60
#include "../jrd/cvt_proto.h"
 
61
#include "../jrd/err_proto.h"
 
62
#include "../jrd/fun_proto.h"
 
63
#include "../jrd/gds_proto.h"
 
64
#include "../jrd/met_proto.h"
 
65
#include "../jrd/par_proto.h"
 
66
#include "../jrd/thd.h"
 
67
#include "../common/utils_proto.h"
 
68
#include "../jrd/SysFunction.h"
 
69
 
 
70
 
 
71
/* blr type classes */
 
72
 
 
73
const int OTHER                 = 0;
 
74
const int STATEMENT             = 1;
 
75
const int TYPE_BOOL             = 2;
 
76
const int VALUE                 = 3;
 
77
const int TYPE_RSE              = 4;
 
78
const int RELATION              = 5;
 
79
const int ACCESS_TYPE   = 6;
 
80
 
 
81
using namespace Jrd;
 
82
 
 
83
#include "gen/blrtable.h"
 
84
 
 
85
 
 
86
 
 
87
static const TEXT elements[][14] =
 
88
        { "", "statement", "boolean", "value", "RecordSelExpr", "TABLE" };
 
89
 
 
90
#include "gen/codetext.h"
 
91
 
 
92
 
 
93
static void error(CompilerScratch*, ...);
 
94
static SSHORT find_proc_field(const jrd_prc*, const Firebird::MetaName&);
 
95
static jrd_nod* par_args(thread_db*, CompilerScratch*, USHORT);
 
96
static jrd_nod* par_cast(thread_db*, CompilerScratch*);
 
97
static PsqlException* par_condition(thread_db*, CompilerScratch*);
 
98
static PsqlException* par_conditions(thread_db*, CompilerScratch*);
 
99
static SSHORT par_context(CompilerScratch*, SSHORT *);
 
100
static void par_dependency(thread_db*, CompilerScratch*, SSHORT, SSHORT, const Firebird::MetaName&);
 
101
static jrd_nod* par_exec_proc(thread_db*, CompilerScratch*, SSHORT);
 
102
static jrd_nod* par_fetch(thread_db*, CompilerScratch*, jrd_nod*);
 
103
static jrd_nod* par_field(thread_db*, CompilerScratch*, SSHORT);
 
104
static jrd_nod* par_function(thread_db*, CompilerScratch*);
 
105
static jrd_nod* par_literal(thread_db*, CompilerScratch*);
 
106
static jrd_nod* par_map(thread_db*, CompilerScratch*, USHORT);
 
107
static jrd_nod* par_message(thread_db*, CompilerScratch*);
 
108
static jrd_nod* par_modify(thread_db*, CompilerScratch*, SSHORT);
 
109
static USHORT par_name(CompilerScratch*, Firebird::MetaName&);
 
110
static size_t par_name(CompilerScratch* csb, Firebird::string& name);
 
111
static jrd_nod* par_plan(thread_db*, CompilerScratch*);
 
112
static jrd_nod* par_procedure(thread_db*, CompilerScratch*, SSHORT);
 
113
static void par_procedure_parms(thread_db*, CompilerScratch*, jrd_prc*, jrd_nod**,
 
114
        jrd_nod**, bool);
 
115
static jrd_nod* par_relation(thread_db*, CompilerScratch*, SSHORT, bool);
 
116
static jrd_nod* par_rse(thread_db*, CompilerScratch*, SSHORT);
 
117
static jrd_nod* par_sort(thread_db*, CompilerScratch*, bool);
 
118
#ifdef NOT_USED_OR_REPLACED
 
119
static jrd_nod* par_stream(thread_db*, CompilerScratch*);
 
120
#endif
 
121
static jrd_nod* par_sys_function(thread_db*, CompilerScratch*);
 
122
static jrd_nod* par_union(thread_db*, CompilerScratch*, bool);
 
123
static USHORT par_word(CompilerScratch*);
 
124
static jrd_nod* parse(thread_db*, CompilerScratch*, USHORT, USHORT expected_optional = 0);
 
125
static void syntax_error(CompilerScratch*, const TEXT*);
 
126
static void warning(CompilerScratch*, ...);
 
127
 
 
128
#define BLR_PEEK        *(csb->csb_running)
 
129
#define BLR_BYTE        *(csb->csb_running)++
 
130
#define BLR_PUSH        (csb->csb_running)--
 
131
#define BLR_WORD        par_word (csb)
 
132
 
 
133
 
 
134
jrd_nod* PAR_blr(thread_db*     tdbb,
 
135
                        jrd_rel*                relation,
 
136
                        const UCHAR*    blr,
 
137
                        CompilerScratch*        view_csb,
 
138
                        CompilerScratch**       csb_ptr,
 
139
                        jrd_req**       request_ptr,
 
140
                        const bool trigger,
 
141
                        USHORT  flags)
 
142
{
 
143
/**************************************
 
144
 *
 
145
 *      P A R _ b l r
 
146
 *
 
147
 **************************************
 
148
 *
 
149
 * Functional description
 
150
 *      Parse blr, returning a compiler scratch block with the results.
 
151
 *      Caller must do pool handling.
 
152
 *
 
153
 **************************************/
 
154
        SET_TDBB(tdbb);
 
155
 
 
156
#ifdef CMP_DEBUG
 
157
        cmp_trace("BLR code given for JRD parsing:");
 
158
        // CVC: Couldn't find isc_trace_printer, so changed it to gds__trace_printer.
 
159
        gds__print_blr(blr, gds__trace_printer, 0, 0);
 
160
#endif
 
161
 
 
162
        CompilerScratch* csb;
 
163
        if (!(csb_ptr && (csb = *csb_ptr))) {
 
164
                size_t count = 5;
 
165
                if (view_csb)
 
166
                        count += view_csb->csb_rpt.getCapacity();
 
167
                csb = CompilerScratch::newCsb(*tdbb->getDefaultPool(), count);
 
168
                csb->csb_g_flags |= flags;
 
169
        }
 
170
 
 
171
/* If there is a request ptr, this is a trigger.  Set up contexts 0 and 1 for
 
172
   the target relation */
 
173
 
 
174
        if (trigger) {
 
175
                SSHORT stream = csb->nextStream();
 
176
                CompilerScratch::csb_repeat* t1 = CMP_csb_element(csb, 0);
 
177
                t1->csb_flags |= csb_used | csb_active | csb_trigger;
 
178
                t1->csb_relation = relation;
 
179
                t1->csb_stream = (UCHAR) stream;
 
180
 
 
181
                stream = csb->nextStream();
 
182
                t1 = CMP_csb_element(csb, 1);
 
183
                t1->csb_flags |= csb_used | csb_active | csb_trigger;
 
184
                t1->csb_relation = relation;
 
185
                t1->csb_stream = (UCHAR) stream;
 
186
        }
 
187
        else if (relation) {
 
188
                CompilerScratch::csb_repeat* t1 = CMP_csb_element(csb, 0);
 
189
                t1->csb_stream = csb->nextStream();
 
190
                t1->csb_relation = relation;
 
191
                t1->csb_flags = csb_used | csb_active;
 
192
        }
 
193
 
 
194
        csb->csb_running = csb->csb_blr = blr;
 
195
 
 
196
        if (view_csb) {
 
197
                CompilerScratch::rpt_itr ptr = view_csb->csb_rpt.begin();
 
198
                // AB: csb_n_stream replaced by view_csb->csb_rpt.getCount(), because there could
 
199
                // be more then just csb_n_stream-numbers that hold data. 
 
200
                // Certainly csb_stream (see par_context where the context is retrieved)
 
201
                const CompilerScratch::rpt_const_itr end = view_csb->csb_rpt.end();
 
202
                for (SSHORT stream = 0; ptr != end; ++ptr, ++stream) {
 
203
                        CompilerScratch::csb_repeat* t2 = CMP_csb_element(csb, stream);
 
204
                        t2->csb_relation = ptr->csb_relation;
 
205
                        t2->csb_stream = ptr->csb_stream;
 
206
                        t2->csb_flags = ptr->csb_flags & csb_used;
 
207
                }
 
208
                csb->csb_n_stream = view_csb->csb_n_stream;
 
209
        }
 
210
 
 
211
        const SSHORT version = *csb->csb_running++;
 
212
 
 
213
        if (version != blr_version4 && version != blr_version5) {
 
214
                error(csb, isc_metadata_corrupt,
 
215
                          isc_arg_gds, isc_wroblrver,
 
216
                          isc_arg_number, (SLONG) blr_version4,
 
217
                          isc_arg_number, (SLONG) version, 0);
 
218
        }
 
219
 
 
220
        if (version == blr_version4)
 
221
                csb->csb_g_flags |= csb_blr_version4;
 
222
 
 
223
        jrd_nod* node = parse(tdbb, csb, OTHER);
 
224
        csb->csb_node = node;
 
225
 
 
226
        if (*csb->csb_running++ != (UCHAR) blr_eoc)
 
227
                syntax_error(csb, "end_of_command");
 
228
 
 
229
        if (request_ptr)
 
230
                *request_ptr = CMP_make_request(tdbb, csb);
 
231
 
 
232
        if (csb_ptr)
 
233
                *csb_ptr = csb;
 
234
        else
 
235
                delete csb;
 
236
 
 
237
        return node;
 
238
}
 
239
 
 
240
 
 
241
USHORT PAR_desc(thread_db* tdbb, CompilerScratch* csb, DSC* desc, ItemInfo* itemInfo)
 
242
{
 
243
/**************************************
 
244
 *
 
245
 *      P A R _ d e s c 
 
246
 *
 
247
 **************************************
 
248
 *
 
249
 * Functional description
 
250
 *      Parse a BLR descriptor.  Return the alignment requirements
 
251
 *      of the datatype.
 
252
 *
 
253
 **************************************/
 
254
        if (itemInfo)
 
255
        {
 
256
                itemInfo->nullable = true;
 
257
                itemInfo->explicitCollation = false;
 
258
                itemInfo->fullDomain = false;
 
259
        }
 
260
 
 
261
        desc->dsc_scale = 0;
 
262
        desc->dsc_sub_type = 0;
 
263
        desc->dsc_address = NULL;
 
264
        desc->dsc_flags = 0;
 
265
 
 
266
        const USHORT dtype = BLR_BYTE;
 
267
 
 
268
        switch (dtype)
 
269
        {
 
270
        case blr_not_nullable:
 
271
                PAR_desc(tdbb, csb, desc, itemInfo);
 
272
                if (itemInfo)
 
273
                        itemInfo->nullable = false;
 
274
                break;
 
275
 
 
276
        case blr_text:
 
277
                desc->dsc_dtype = dtype_text;
 
278
                desc->dsc_flags |= DSC_no_subtype;
 
279
                desc->dsc_length = BLR_WORD;
 
280
                INTL_ASSIGN_TTYPE(desc, ttype_dynamic);
 
281
                break;
 
282
 
 
283
        case blr_cstring:
 
284
                desc->dsc_dtype = dtype_cstring;
 
285
                desc->dsc_flags |= DSC_no_subtype;
 
286
                desc->dsc_length = BLR_WORD;
 
287
                INTL_ASSIGN_TTYPE(desc, ttype_dynamic);
 
288
                break;
 
289
 
 
290
        case blr_varying:
 
291
                desc->dsc_dtype = dtype_varying;
 
292
                desc->dsc_flags |= DSC_no_subtype;
 
293
                desc->dsc_length = BLR_WORD + sizeof(USHORT);
 
294
                INTL_ASSIGN_TTYPE(desc, ttype_dynamic);
 
295
                break;
 
296
 
 
297
        case blr_text2:
 
298
                desc->dsc_dtype = dtype_text;
 
299
                INTL_ASSIGN_TTYPE(desc, BLR_WORD);
 
300
                desc->dsc_length = BLR_WORD;
 
301
                break;
 
302
 
 
303
        case blr_cstring2:
 
304
                desc->dsc_dtype = dtype_cstring;
 
305
                INTL_ASSIGN_TTYPE(desc, BLR_WORD);
 
306
                desc->dsc_length = BLR_WORD;
 
307
                break;
 
308
 
 
309
        case blr_varying2:
 
310
                desc->dsc_dtype = dtype_varying;
 
311
                INTL_ASSIGN_TTYPE(desc, BLR_WORD);
 
312
                desc->dsc_length = BLR_WORD + sizeof(USHORT);
 
313
                break;
 
314
 
 
315
        case blr_short:
 
316
                desc->dsc_dtype = dtype_short;
 
317
                desc->dsc_length = sizeof(SSHORT);
 
318
                desc->dsc_scale = (int) BLR_BYTE;
 
319
                break;
 
320
 
 
321
        case blr_long:
 
322
                desc->dsc_dtype = dtype_long;
 
323
                desc->dsc_length = sizeof(SLONG);
 
324
                desc->dsc_scale = (int) BLR_BYTE;
 
325
                break;
 
326
 
 
327
        case blr_int64:
 
328
                desc->dsc_dtype = dtype_int64;
 
329
                desc->dsc_length = sizeof(SINT64);
 
330
                desc->dsc_scale = (int) BLR_BYTE;
 
331
                break;
 
332
 
 
333
        case blr_quad:
 
334
                desc->dsc_dtype = dtype_quad;
 
335
                desc->dsc_length = sizeof(ISC_QUAD);
 
336
                desc->dsc_scale = (int) BLR_BYTE;
 
337
                break;
 
338
 
 
339
        case blr_float:
 
340
                desc->dsc_dtype = dtype_real;
 
341
                desc->dsc_length = sizeof(float);
 
342
                break;
 
343
 
 
344
        case blr_timestamp:
 
345
                desc->dsc_dtype = dtype_timestamp;
 
346
                desc->dsc_length = sizeof(ISC_QUAD);
 
347
                break;
 
348
 
 
349
        case blr_sql_date:
 
350
                desc->dsc_dtype = dtype_sql_date;
 
351
                desc->dsc_length = type_lengths[dtype_sql_date];
 
352
                break;
 
353
 
 
354
        case blr_sql_time:
 
355
                desc->dsc_dtype = dtype_sql_time;
 
356
                desc->dsc_length = type_lengths[dtype_sql_time];
 
357
                break;
 
358
 
 
359
        case blr_double:
 
360
#ifndef VMS
 
361
        case blr_d_float:
 
362
#endif
 
363
                desc->dsc_dtype = dtype_double;
 
364
                desc->dsc_length = sizeof(double);
 
365
                break;
 
366
 
 
367
#ifdef VMS
 
368
        case blr_d_float:
 
369
                desc->dsc_dtype = dtype_d_float;
 
370
                desc->dsc_length = sizeof(double);
 
371
                break;
 
372
#endif
 
373
 
 
374
        case blr_blob2:
 
375
                {
 
376
                        desc->dsc_dtype = dtype_blob;
 
377
                        desc->dsc_length = sizeof(ISC_QUAD);
 
378
                        desc->dsc_sub_type = BLR_WORD;
 
379
 
 
380
                        USHORT ttype = BLR_WORD;
 
381
                        desc->dsc_scale = ttype & 0xFF;         // BLOB character set
 
382
                        desc->dsc_flags = ttype & 0xFF00;       // BLOB collation
 
383
                        break;
 
384
                }
 
385
 
 
386
        case blr_domain_name:
 
387
        case blr_domain_name2:
 
388
                {
 
389
                        bool fullDomain = (BLR_BYTE == blr_domain_full);
 
390
                        Firebird::MetaName* name = FB_NEW(csb->csb_pool) Firebird::MetaName(csb->csb_pool);
 
391
                        par_name(csb, *name);
 
392
 
 
393
                        FieldInfo fieldInfo;
 
394
                        bool exist = csb->csb_map_field_info.get(*name, fieldInfo);
 
395
                        MET_get_domain(tdbb, *name, desc, (exist ? NULL : &fieldInfo));
 
396
 
 
397
                        if (!exist)
 
398
                                csb->csb_map_field_info.put(*name, fieldInfo);
 
399
 
 
400
                        if (itemInfo)
 
401
                        {
 
402
                                itemInfo->field = *name;
 
403
 
 
404
                                if (fullDomain)
 
405
                                {
 
406
                                        itemInfo->nullable = fieldInfo.nullable;
 
407
                                        itemInfo->fullDomain = true;
 
408
                                }
 
409
                                else
 
410
                                        itemInfo->nullable = true;
 
411
                        }
 
412
 
 
413
                        if (dtype == blr_domain_name2)
 
414
                        {
 
415
                                USHORT ttype = BLR_WORD;
 
416
 
 
417
                                switch (desc->dsc_dtype)
 
418
                                {
 
419
                                        case dtype_cstring:
 
420
                                        case dtype_text:
 
421
                                        case dtype_varying:
 
422
                                                INTL_ASSIGN_TTYPE(desc, ttype);
 
423
                                                break;
 
424
 
 
425
                                        case dtype_blob:
 
426
                                                desc->dsc_scale = ttype & 0xFF;         // BLOB character set
 
427
                                                desc->dsc_flags = ttype & 0xFF00;       // BLOB collation
 
428
                                                break;
 
429
 
 
430
                                        default:
 
431
                                                error(csb, isc_collation_requires_text, 0);
 
432
                                                break;
 
433
                                }
 
434
                        }
 
435
 
 
436
                        jrd_nod* dep_node = PAR_make_node(tdbb, e_dep_length);
 
437
                        dep_node->nod_type = nod_dependency;
 
438
                        dep_node->nod_arg[e_dep_object] = (jrd_nod*) name;
 
439
                        dep_node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_field;
 
440
                        csb->csb_dependencies.push(dep_node);
 
441
 
 
442
                        break;
 
443
                }
 
444
 
 
445
        default:
 
446
                error(csb, isc_datnotsup, 0);
 
447
        }
 
448
 
 
449
        if (itemInfo)
 
450
        {
 
451
                if (dtype == blr_cstring2 || dtype == blr_text2 || dtype == blr_varying2 ||
 
452
                        dtype == blr_blob2 || dtype == blr_domain_name2)
 
453
                {
 
454
                        itemInfo->explicitCollation = true;
 
455
                }
 
456
        }
 
457
 
 
458
        return type_alignments[desc->dsc_dtype];
 
459
}
 
460
 
 
461
 
 
462
jrd_nod* PAR_gen_field(thread_db* tdbb, USHORT stream, USHORT id)
 
463
{
 
464
/**************************************
 
465
 *
 
466
 *      P A R _ g e n _ f i e l d
 
467
 *
 
468
 **************************************
 
469
 *
 
470
 * Functional description
 
471
 *      Generate a field block.
 
472
 *
 
473
 **************************************/
 
474
        SET_TDBB(tdbb);
 
475
 
 
476
        jrd_nod* node = FB_NEW_RPT(*tdbb->getDefaultPool(), e_fld_length) jrd_nod();
 
477
        node->nod_type = nod_field;
 
478
        node->nod_arg[e_fld_id] = (jrd_nod*) (IPTR) id;
 
479
        node->nod_arg[e_fld_stream] = (jrd_nod*) (IPTR) stream;
 
480
 
 
481
        return node;
 
482
}
 
483
 
 
484
 
 
485
jrd_nod* PAR_make_field(thread_db* tdbb, CompilerScratch* csb, 
 
486
                                                USHORT context,
 
487
                                                const Firebird::MetaName& base_field)
 
488
{
 
489
/**************************************
 
490
 *
 
491
 *      P A R _ m a k e _ f i e l d
 
492
 *
 
493
 **************************************
 
494
 *
 
495
 * Functional description
 
496
 *      Make up a field node in the permanent pool.  This is used
 
497
 *      by MET_scan_relation to handle view fields.
 
498
 *
 
499
 **************************************/
 
500
        SET_TDBB(tdbb);
 
501
 
 
502
        const USHORT stream = csb->csb_rpt[context].csb_stream;
 
503
 
 
504
    /* CVC: This is just another case of a custom function that isn't prepared
 
505
       for quoted identifiers and that causes views with fields names like "z x"
 
506
       to fail miserably. Since this function was truncating field names like "z x",
 
507
       MET_lookup_field() call below failed and hence the function returned NULL
 
508
       so only caller MET_scan_relation() did field->fld_source = 0;
 
509
       This means a field without entry in rdb$fields. This is the origin of the
 
510
       mysterious message "cannot access column z x in view VF" when selecting from
 
511
       such view that has field "z x". This closes Firebird Bug #227758. */
 
512
        // solved by using MetaName& as parameter - AP
 
513
        jrd_rel* relation = csb->csb_rpt[stream].csb_relation;
 
514
        jrd_prc* procedure = csb->csb_rpt[stream].csb_procedure;
 
515
 
 
516
        const SSHORT id = procedure ? find_proc_field(procedure, base_field) :
 
517
                MET_lookup_field (tdbb, csb->csb_rpt[stream].csb_relation, base_field, 0);
 
518
 
 
519
        if (id < 0)
 
520
                return NULL;
 
521
 
 
522
/* If rel_fields is NULL this means that the relation is
 
523
 * in a temporary state (partially loaded).  In this case
 
524
 * there is nothing we can do but post an error and exit.
 
525
 * Note: This will most likely happen if we have a large list
 
526
 * of deferred work which can not complete because of some
 
527
 * error, and while we are trying to commit, we find 
 
528
 * that we have a dependency on something later in the list.
 
529
 * IF there were no error, then the dependency woyld have
 
530
 * been resolved, because we would have fully loaded the
 
531
 * relation, but if it can not be loaded, then we have this
 
532
 * problem. The only thing that can be done to remedy this
 
533
 * problem is to rollback.  This will clear the DeferredWork list and
 
534
 * allow the user to remedy the original error.  Note: it would
 
535
 * be incorrect for us (the server) to perform the rollback
 
536
 * implicitly, because this is a task for the user to do, and
 
537
 * should never be decided by the server. This fixes bug 10052 */
 
538
 
 
539
        // CVC: The code for procedures now compiles correctly, but Vlad has
 
540
        // pointed out that we don't have default for output fields, therefore
 
541
        // the code is commented till better times.
 
542
        jrd_fld* field = NULL;
 
543
        /*
 
544
        Parameter* param = NULL;
 
545
 
 
546
        if (procedure)
 
547
        {
 
548
                param = (*procedure->prc_output_fields)[id];
 
549
        }
 
550
        else
 
551
        */
 
552
        if (relation)
 
553
        {
 
554
                if (!relation->rel_fields) {
 
555
                        ERR_post(isc_depend_on_uncommitted_rel, 0);
 
556
                }
 
557
                field = (*relation->rel_fields)[id];
 
558
        }
 
559
 
 
560
        if (csb->csb_g_flags & csb_get_dependencies) {
 
561
                par_dependency(tdbb, csb, stream, id, base_field);
 
562
        }
 
563
 
 
564
        jrd_nod* temp_node = PAR_gen_field(tdbb, stream, id);
 
565
        /*
 
566
        if (param)
 
567
        {
 
568
                if (param->prm_default_value) //&& param->prm_not_null)
 
569
                        temp_node->nod_arg[e_fld_default_value] =
 
570
                                param->prm_default_value;
 
571
        }
 
572
        else
 
573
        */
 
574
        if (field) 
 
575
        {
 
576
                if (field->fld_default_value && field->fld_not_null)
 
577
                        temp_node->nod_arg[e_fld_default_value] = field->fld_default_value;
 
578
        }
 
579
 
 
580
        return temp_node;
 
581
}
 
582
 
 
583
 
 
584
jrd_nod* PAR_make_list(thread_db* tdbb, NodeStack& stack)
 
585
{
 
586
/**************************************
 
587
 *
 
588
 *      P A R _ m a k e _ l i s t
 
589
 *
 
590
 **************************************
 
591
 *
 
592
 * Functional description
 
593
 *      Make a list node out of a stack.
 
594
 *
 
595
 **************************************/
 
596
        SET_TDBB(tdbb);
 
597
 
 
598
/* Count the number of nodes */
 
599
        USHORT count = stack.getCount();
 
600
 
 
601
        jrd_nod* node = PAR_make_node(tdbb, count);
 
602
        node->nod_type = nod_list;
 
603
        jrd_nod** ptr = node->nod_arg + count;
 
604
 
 
605
        while (stack.hasData()) 
 
606
        {
 
607
                *--ptr = stack.pop();
 
608
        }
 
609
 
 
610
        return node;
 
611
}
 
612
 
 
613
 
 
614
jrd_nod* PAR_make_node(thread_db* tdbb, int size)
 
615
{
 
616
/**************************************
 
617
 *
 
618
 *      P A R _ m a k e _ n o d e
 
619
 *
 
620
 **************************************
 
621
 *
 
622
 * Functional description
 
623
 *      Make a node element and pass it back.
 
624
 *
 
625
 **************************************/
 
626
        SET_TDBB(tdbb);
 
627
 
 
628
        jrd_nod* node = FB_NEW_RPT(*tdbb->getDefaultPool(), size) jrd_nod();
 
629
        node->nod_count = size;
 
630
 
 
631
        return node;
 
632
}
 
633
 
 
634
 
 
635
CompilerScratch* PAR_parse(thread_db* tdbb, const UCHAR* blr, USHORT internal_flag,
 
636
                                                   USHORT dbginfo_length, const UCHAR* dbginfo)
 
637
{
 
638
/**************************************
 
639
 *
 
640
 *      P A R _ p a r s e
 
641
 *
 
642
 **************************************
 
643
 *
 
644
 * Functional description
 
645
 *      Parse blr, returning a compiler scratch block with the results.
 
646
 *
 
647
 **************************************/
 
648
        SET_TDBB(tdbb);
 
649
 
 
650
        CompilerScratch* csb = CompilerScratch::newCsb(*tdbb->getDefaultPool(), 5);
 
651
        csb->csb_running = csb->csb_blr = blr;
 
652
        const SSHORT version = *csb->csb_running++;
 
653
        if (internal_flag)
 
654
                csb->csb_g_flags |= csb_internal;
 
655
 
 
656
        if (version != blr_version4 && version != blr_version5)
 
657
        {
 
658
                error(csb, isc_wroblrver,
 
659
                          isc_arg_number, (SLONG) blr_version4,
 
660
                          isc_arg_number, (SLONG) version, 0);
 
661
        }
 
662
 
 
663
        if (version == blr_version4)
 
664
        {
 
665
                csb->csb_g_flags |= csb_blr_version4;
 
666
        }
 
667
 
 
668
        if (dbginfo_length > 0)
 
669
                DBG_parse_debug_info(dbginfo_length, dbginfo, csb->csb_dbg_info);
 
670
 
 
671
        jrd_nod* node = parse(tdbb, csb, OTHER);
 
672
        csb->csb_node = node;
 
673
 
 
674
        if (*csb->csb_running++ != (UCHAR) blr_eoc)
 
675
        {
 
676
                syntax_error(csb, "end_of_command");
 
677
        }
 
678
 
 
679
        return csb;
 
680
}
 
681
 
 
682
 
 
683
SLONG PAR_symbol_to_gdscode(const Firebird::MetaName& name)
 
684
{
 
685
/**************************************
 
686
 *
 
687
 *      P A R _ s y m b o l _ t o _ g d s c o d e
 
688
 *
 
689
 **************************************
 
690
 *
 
691
 * Functional description
 
692
 *      Symbolic ASCII names are used in blr for posting and handling
 
693
 *      exceptions.  They are also used to identify error codes
 
694
 *      within system triggers in a database.
 
695
 *
 
696
 *      Returns the gds error status code for the given symbolic
 
697
 *      name, or 0 if not found.
 
698
 *
 
699
 *      Symbolic names may be null or space terminated.
 
700
 *
 
701
 **************************************/
 
702
 
 
703
        for (int i = 0; codes[i].code_number; ++i) {
 
704
                if (name == codes[i].code_string) {
 
705
                        return codes[i].code_number;
 
706
                }
 
707
        }
 
708
 
 
709
        return 0;
 
710
}
 
711
 
 
712
 
 
713
static void error(CompilerScratch* csb, ...)
 
714
{
 
715
/**************************************
 
716
 *
 
717
 *      e r r o r
 
718
 *
 
719
 **************************************
 
720
 *
 
721
 * Functional description
 
722
 *      We've got a blr error other than a syntax error.  Handle it.
 
723
 *
 
724
 **************************************/
 
725
        ISC_STATUS *p;
 
726
        USHORT offset;
 
727
        int type;
 
728
        va_list args;
 
729
 
 
730
/* Don't bother to pass tdbb for error handling */
 
731
        thread_db* tdbb = JRD_get_thread_data();
 
732
 
 
733
        va_start(args, csb);
 
734
 
 
735
        csb->csb_running--;
 
736
        offset = csb->csb_running - csb->csb_blr;
 
737
        p = tdbb->tdbb_status_vector;
 
738
        *p++ = isc_arg_gds;
 
739
        *p++ = isc_invalid_blr;
 
740
        *p++ = isc_arg_number;
 
741
        *p++ = offset;
 
742
 
 
743
        *p++ = isc_arg_gds;
 
744
        *p++ = va_arg(args, ISC_STATUS);
 
745
 
 
746
/* Pick up remaining args */
 
747
 
 
748
        while ( (*p++ = type = va_arg(args, int)) )
 
749
        {
 
750
                switch (type) {
 
751
                case isc_arg_gds:
 
752
                        *p++ = (ISC_STATUS) va_arg(args, ISC_STATUS);
 
753
                        break;
 
754
 
 
755
                case isc_arg_string:
 
756
                case isc_arg_interpreted:
 
757
                        *p++ = (ISC_STATUS) va_arg(args, TEXT *);
 
758
                        break;
 
759
 
 
760
                case isc_arg_cstring:
 
761
                        *p++ = (ISC_STATUS) va_arg(args, int);
 
762
                        *p++ = (ISC_STATUS) va_arg(args, TEXT *);
 
763
                        break;
 
764
 
 
765
                case isc_arg_number:
 
766
                        *p++ = (ISC_STATUS) va_arg(args, SLONG);
 
767
                        break;
 
768
 
 
769
                default:
 
770
                        fb_assert(FALSE);
 
771
                case isc_arg_vms:
 
772
                case isc_arg_unix:
 
773
                case isc_arg_win32:
 
774
                        *p++ = va_arg(args, int);   
 
775
                        break; 
 
776
                }
 
777
        }
 
778
        va_end(args);
 
779
 
 
780
/* Give up whatever we were doing and return to the user. */
 
781
 
 
782
        ERR_punt();
 
783
}
 
784
 
 
785
 
 
786
static SSHORT find_proc_field(const jrd_prc* procedure, const Firebird::MetaName& name)
 
787
{
 
788
/**************************************
 
789
 *
 
790
 *      f i n d _ p r o c _ f i e l d
 
791
 *
 
792
 **************************************
 
793
 *
 
794
 * Functional description
 
795
 *      Look for named field in procedure output fields.
 
796
 *
 
797
 **************************************/
 
798
        vec<Parameter*>* list = procedure->prc_output_fields;
 
799
        vec<Parameter*>::const_iterator ptr = list->begin();
 
800
        for (const vec<Parameter*>::const_iterator end = list->end(); ptr < end; ++ptr)
 
801
        {
 
802
                const Parameter* param = *ptr;
 
803
                if (name == param->prm_name)
 
804
                        return param->prm_number;
 
805
        }
 
806
 
 
807
        return -1;
 
808
}
 
809
 
 
810
 
 
811
static jrd_nod* par_args(thread_db* tdbb, CompilerScratch* csb, USHORT expected)
 
812
{
 
813
/**************************************
 
814
 *
 
815
 *      p a r _ a r g s
 
816
 *
 
817
 **************************************
 
818
 *
 
819
 * Functional description
 
820
 *      Parse a counted argument list.
 
821
 *
 
822
 **************************************/
 
823
        SET_TDBB(tdbb);
 
824
 
 
825
        USHORT count = BLR_BYTE;
 
826
        jrd_nod* node = PAR_make_node(tdbb, count);
 
827
        node->nod_type = nod_list;
 
828
        jrd_nod** ptr = node->nod_arg;
 
829
 
 
830
        if (count) {
 
831
                do {
 
832
                        *ptr++ = parse(tdbb, csb, expected);
 
833
                } while (--count);
 
834
        }
 
835
 
 
836
        return node;
 
837
}
 
838
 
 
839
 
 
840
static jrd_nod* par_cast(thread_db* tdbb, CompilerScratch* csb)
 
841
{
 
842
/**************************************
 
843
 *
 
844
 *      p a r _ c a s t
 
845
 *
 
846
 **************************************
 
847
 *
 
848
 * Functional description
 
849
 *      Parse a datatype cast
 
850
 *
 
851
 **************************************/
 
852
        SET_TDBB(tdbb);
 
853
 
 
854
        jrd_nod* node = PAR_make_node(tdbb, e_cast_length);
 
855
        node->nod_count = count_table[blr_cast];
 
856
 
 
857
        Format* format = Format::newFormat(*tdbb->getDefaultPool(), 1);
 
858
        node->nod_arg[e_cast_fmt] = (jrd_nod*) format;
 
859
 
 
860
        dsc* desc = &format->fmt_desc[0];
 
861
        ItemInfo itemInfo;
 
862
        PAR_desc(tdbb, csb, desc, &itemInfo);
 
863
        format->fmt_length = desc->dsc_length;
 
864
 
 
865
        node->nod_arg[e_cast_source] = parse(tdbb, csb, VALUE);
 
866
 
 
867
        if (itemInfo.isSpecial())
 
868
        {
 
869
                ItemInfo* p = FB_NEW(*tdbb->getDefaultPool()) ItemInfo(*tdbb->getDefaultPool(), itemInfo);
 
870
                node->nod_arg[e_cast_iteminfo] = (jrd_nod*) p;
 
871
        }
 
872
 
 
873
        if (itemInfo.explicitCollation)
 
874
        {
 
875
                jrd_nod* dep_node = PAR_make_node (tdbb, e_dep_length);
 
876
                dep_node->nod_type = nod_dependency;
 
877
                dep_node->nod_arg [e_dep_object] = (jrd_nod*)(IPTR) INTL_TEXT_TYPE(*desc);
 
878
                dep_node->nod_arg [e_dep_object_type] = (jrd_nod*)(IPTR) obj_collation;
 
879
                csb->csb_dependencies.push(dep_node);
 
880
        }
 
881
 
 
882
        return node;
 
883
}
 
884
 
 
885
 
 
886
static PsqlException* par_condition(thread_db* tdbb, CompilerScratch* csb)
 
887
{
 
888
/**************************************
 
889
 *
 
890
 *      p a r _ c o n d i t i o n
 
891
 *
 
892
 **************************************
 
893
 *
 
894
 * Functional description
 
895
 *      Parse an error conditions list.
 
896
 *
 
897
 **************************************/
 
898
        jrd_nod* dep_node;
 
899
        SLONG code_number;
 
900
        Firebird::MetaName name;
 
901
 
 
902
        SET_TDBB(tdbb);
 
903
 
 
904
/* allocate a node to represent the conditions list */
 
905
 
 
906
        const USHORT code_type = BLR_BYTE;
 
907
 
 
908
        /* don't create PsqlException if blr_raise is used,
 
909
           just return NULL */
 
910
        if (code_type == blr_raise)
 
911
        {
 
912
                return NULL;
 
913
        }
 
914
 
 
915
        PsqlException* exception_list = FB_NEW_RPT(*tdbb->getDefaultPool(), 1) PsqlException();
 
916
        exception_list->xcp_count = 1;
 
917
        xcp_repeat& item = exception_list->xcp_rpt[0];
 
918
        
 
919
        switch (code_type) {
 
920
        case blr_sql_code:
 
921
                item.xcp_type = xcp_sql_code;
 
922
                item.xcp_code = (SSHORT) BLR_WORD;
 
923
                break;
 
924
 
 
925
        case blr_gds_code:
 
926
                item.xcp_type = xcp_gds_code;
 
927
                par_name(csb, name);
 
928
                name.lower7();
 
929
                code_number = PAR_symbol_to_gdscode(name);
 
930
                if (code_number)
 
931
                        item.xcp_code = code_number;
 
932
                else
 
933
                        error(csb, isc_codnotdef, isc_arg_string, ERR_cstring(name), 0);
 
934
                break;
 
935
 
 
936
        case blr_exception:
 
937
        case blr_exception_msg:
 
938
                item.xcp_type = xcp_xcp_code;
 
939
                par_name(csb, name);
 
940
                if (!(item.xcp_code = MET_lookup_exception_number(tdbb, name)))
 
941
                        error(csb, isc_xcpnotdef, isc_arg_string, ERR_cstring(name), 0);
 
942
                dep_node = PAR_make_node(tdbb, e_dep_length);
 
943
                dep_node->nod_type = nod_dependency;
 
944
                dep_node->nod_arg[e_dep_object] = (jrd_nod*)(IPTR) item.xcp_code;
 
945
                dep_node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_exception;
 
946
                csb->csb_dependencies.push(dep_node);
 
947
                break;
 
948
 
 
949
        default:
 
950
                fb_assert(FALSE);
 
951
                break;
 
952
        }
 
953
 
 
954
        return exception_list;
 
955
}
 
956
 
 
957
 
 
958
static PsqlException* par_conditions(thread_db* tdbb, CompilerScratch* csb)
 
959
{
 
960
/**************************************
 
961
 *
 
962
 *      p a r _ c o n d i t i o n s
 
963
 *
 
964
 **************************************
 
965
 *
 
966
 * Functional description
 
967
 *      Parse an error conditions list.
 
968
 *
 
969
 **************************************/
 
970
        jrd_nod* dep_node;
 
971
        SLONG code_number;
 
972
        Firebird::MetaName name;
 
973
 
 
974
        SET_TDBB(tdbb);
 
975
 
 
976
/* allocate a node to represent the conditions list */
 
977
 
 
978
        const USHORT n = BLR_WORD;
 
979
        PsqlException* exception_list = FB_NEW_RPT(*tdbb->getDefaultPool(), n) PsqlException();
 
980
        exception_list->xcp_count = n;
 
981
        for (int i = 0; i < n; i++) {
 
982
                const USHORT code_type = BLR_BYTE;
 
983
                xcp_repeat& item = exception_list->xcp_rpt[i];
 
984
                
 
985
                switch (code_type) {
 
986
                case blr_sql_code:
 
987
                        item.xcp_type = xcp_sql_code;
 
988
                        item.xcp_code = (SSHORT) BLR_WORD;
 
989
                        break;
 
990
 
 
991
                case blr_gds_code:
 
992
                        item.xcp_type = xcp_gds_code;
 
993
                        par_name(csb, name);
 
994
                        name.lower7();
 
995
                        code_number = PAR_symbol_to_gdscode(name);
 
996
                        if (code_number)
 
997
                                item.xcp_code = code_number;
 
998
                        else
 
999
                                error(csb, isc_codnotdef, isc_arg_string, ERR_cstring(name), 0);
 
1000
                        break;
 
1001
 
 
1002
                case blr_exception:
 
1003
                        item.xcp_type = xcp_xcp_code;
 
1004
                        par_name(csb, name);
 
1005
                        if (!(item.xcp_code = MET_lookup_exception_number(tdbb, name)))
 
1006
                                error(csb, isc_xcpnotdef, isc_arg_string, ERR_cstring(name), 0);
 
1007
                        dep_node = PAR_make_node(tdbb, e_dep_length);
 
1008
                        dep_node->nod_type = nod_dependency;
 
1009
                        dep_node->nod_arg[e_dep_object] = (jrd_nod*)(IPTR) item.xcp_code;
 
1010
                        dep_node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_exception;
 
1011
                        csb->csb_dependencies.push(dep_node);
 
1012
                        break;
 
1013
 
 
1014
                case blr_default_code:
 
1015
                        item.xcp_type = xcp_default;
 
1016
                        item.xcp_code = 0;
 
1017
                        break;
 
1018
 
 
1019
                default:
 
1020
                        fb_assert(FALSE);
 
1021
                        break;
 
1022
                }
 
1023
        }
 
1024
 
 
1025
        return exception_list;
 
1026
}
 
1027
 
 
1028
 
 
1029
static SSHORT par_context(CompilerScratch* csb, SSHORT* context_ptr)
 
1030
{
 
1031
/**************************************
 
1032
 *
 
1033
 *      p a r _ c o n t e x t
 
1034
 *
 
1035
 **************************************
 
1036
 *
 
1037
 * Functional description
 
1038
 *      Introduce a new context into the system.  This involves 
 
1039
 *      assigning a stream and possibly extending the compile 
 
1040
 *      scratch block.
 
1041
 *
 
1042
 **************************************/
 
1043
 
 
1044
        const SSHORT context = (unsigned int) BLR_BYTE;
 
1045
 
 
1046
        if (context_ptr)
 
1047
                *context_ptr = context;
 
1048
 
 
1049
        CompilerScratch::csb_repeat* tail = CMP_csb_element(csb, context);
 
1050
 
 
1051
        if (tail->csb_flags & csb_used) {
 
1052
                if (csb->csb_g_flags & csb_reuse_context) {
 
1053
                        return tail->csb_stream;
 
1054
                }
 
1055
                else {
 
1056
                        error(csb, isc_ctxinuse, 0);
 
1057
                }
 
1058
        }
 
1059
 
 
1060
        const SSHORT stream = csb->nextStream(false);
 
1061
        if (stream >= MAX_STREAMS)
 
1062
        {
 
1063
                error(csb, isc_too_many_contexts, 0);
 
1064
        }
 
1065
 
 
1066
        tail->csb_flags |= csb_used;
 
1067
        tail->csb_stream = (UCHAR) stream;
 
1068
 
 
1069
        CMP_csb_element(csb, stream);
 
1070
 
 
1071
        return stream;
 
1072
}
 
1073
 
 
1074
 
 
1075
static void par_dependency(thread_db*   tdbb,
 
1076
                                                   CompilerScratch*    csb,
 
1077
                                                   SSHORT stream,
 
1078
                                                   SSHORT id,
 
1079
                                                   const Firebird::MetaName& field_name)
 
1080
{
 
1081
/**************************************
 
1082
 *
 
1083
 *      p a r _ d e p e n d e n c y
 
1084
 *
 
1085
 **************************************
 
1086
 *
 
1087
 * Functional description
 
1088
 *      Register a field, relation, procedure or exception reference
 
1089
 *      as a dependency.
 
1090
 *
 
1091
 **************************************/
 
1092
        SET_TDBB(tdbb);
 
1093
 
 
1094
        jrd_nod* node = PAR_make_node(tdbb, e_dep_length);
 
1095
        node->nod_type = nod_dependency;
 
1096
        if (csb->csb_rpt[stream].csb_relation) {
 
1097
                node->nod_arg[e_dep_object] =
 
1098
                        (jrd_nod*) csb->csb_rpt[stream].csb_relation;
 
1099
                // How do I determine reliably this is a view?
 
1100
                // At this time, rel_view_rse is still null.
 
1101
                //if (is_view)
 
1102
                //      node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_view;
 
1103
                //else
 
1104
                        node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_relation;
 
1105
        }
 
1106
        else if (csb->csb_rpt[stream].csb_procedure) {
 
1107
                node->nod_arg[e_dep_object] =
 
1108
                        (jrd_nod*) csb->csb_rpt[stream].csb_procedure;
 
1109
                node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_procedure;
 
1110
        }
 
1111
 
 
1112
        if (field_name.length() > 0) {
 
1113
                jrd_nod* field_node = PAR_make_node(tdbb, 1);
 
1114
                node->nod_arg[e_dep_field] = field_node;
 
1115
                field_node->nod_type = nod_literal;
 
1116
                field_node->nod_arg[0] = (jrd_nod*) 
 
1117
                        stringDup(*tdbb->getDefaultPool(), field_name.c_str());
 
1118
        }
 
1119
        else if (id >= 0) {
 
1120
                jrd_nod* field_node = PAR_make_node(tdbb, 1);
 
1121
                node->nod_arg[e_dep_field] = field_node;
 
1122
                field_node->nod_type = nod_field;
 
1123
                field_node->nod_arg[0] = (jrd_nod*) (IPTR) id;
 
1124
        }
 
1125
 
 
1126
        csb->csb_dependencies.push(node);
 
1127
}
 
1128
 
 
1129
 
 
1130
static jrd_nod* par_exec_proc(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_operator)
 
1131
{
 
1132
/**************************************
 
1133
 *
 
1134
 *      p a r _ e x e c _ p r o c
 
1135
 *
 
1136
 **************************************
 
1137
 *
 
1138
 * Functional description
 
1139
 *      Parse an execute procedure  reference.
 
1140
 *
 
1141
 **************************************/
 
1142
        SET_TDBB(tdbb);
 
1143
 
 
1144
        jrd_prc* procedure = NULL;
 
1145
        {
 
1146
                Firebird::MetaName name;
 
1147
 
 
1148
                if (blr_operator == blr_exec_pid) {
 
1149
                        const USHORT pid = BLR_WORD;
 
1150
                        if (!(procedure = MET_lookup_procedure_id(tdbb, pid, false, false, 0)))
 
1151
                                name.printf("id %d", pid);
 
1152
                }
 
1153
                else {
 
1154
                        par_name(csb, name);
 
1155
                        procedure = MET_lookup_procedure(tdbb, name, false);
 
1156
                }
 
1157
                if (!procedure)
 
1158
                        error(csb, isc_prcnotdef, isc_arg_string, ERR_cstring(name), 0);
 
1159
        }
 
1160
 
 
1161
        jrd_nod* node = PAR_make_node(tdbb, e_esp_length);
 
1162
        node->nod_type = nod_exec_proc;
 
1163
        node->nod_count = count_table[blr_exec_proc];
 
1164
        node->nod_arg[e_esp_procedure] = (jrd_nod*) procedure;
 
1165
 
 
1166
        par_procedure_parms(tdbb, csb, procedure, &node->nod_arg[e_esp_in_msg],
 
1167
                                                &node->nod_arg[e_esp_inputs], true);
 
1168
        par_procedure_parms(tdbb, csb, procedure, &node->nod_arg[e_esp_out_msg],
 
1169
                                                &node->nod_arg[e_esp_outputs], false);
 
1170
 
 
1171
        jrd_nod* dep_node = PAR_make_node(tdbb, e_dep_length);
 
1172
        dep_node->nod_type = nod_dependency;
 
1173
        dep_node->nod_arg[e_dep_object] = (jrd_nod*) procedure;
 
1174
        dep_node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_procedure;
 
1175
 
 
1176
        csb->csb_dependencies.push(dep_node);
 
1177
 
 
1178
        return node;
 
1179
}
 
1180
 
 
1181
 
 
1182
static jrd_nod* par_fetch(thread_db* tdbb, CompilerScratch* csb, jrd_nod* for_node)
 
1183
{
 
1184
/**************************************
 
1185
 *
 
1186
 *      p a r _ f e t c h
 
1187
 *
 
1188
 **************************************
 
1189
 *
 
1190
 * Functional description
 
1191
 *      Parse a FETCH statement, and map it into
 
1192
 *
 
1193
 *          FOR x IN relation WITH x.DBKEY EQ value ...
 
1194
 *
 
1195
 **************************************/
 
1196
        SET_TDBB(tdbb);
 
1197
 
 
1198
/* Fake RecordSelExpr */
 
1199
 
 
1200
        for_node->nod_arg[e_for_re] = PAR_make_node(tdbb, 1 + rse_delta + 2);
 
1201
        RecordSelExpr* rse = (RecordSelExpr*) for_node->nod_arg[e_for_re];
 
1202
        rse->nod_type = nod_rse;
 
1203
        rse->nod_count = 0;
 
1204
        rse->rse_count = 1;
 
1205
        jrd_nod* relation = parse(tdbb, csb, RELATION);
 
1206
        rse->rse_relation[0] = relation;
 
1207
 
 
1208
/* Fake boolean */
 
1209
 
 
1210
        jrd_nod* node = rse->rse_boolean = PAR_make_node(tdbb, 2);
 
1211
        node->nod_type = nod_eql;
 
1212
        node->nod_flags = nod_comparison;
 
1213
        node->nod_arg[1] = parse(tdbb, csb, VALUE);
 
1214
        node->nod_arg[0] = PAR_make_node(tdbb, 1);
 
1215
        node = node->nod_arg[0];
 
1216
        node->nod_type = nod_dbkey;
 
1217
        node->nod_count = 0;
 
1218
        node->nod_arg[0] = relation->nod_arg[e_rel_stream];
 
1219
 
 
1220
/* Pick up statement */
 
1221
 
 
1222
        for_node->nod_arg[e_for_statement] = parse(tdbb, csb, STATEMENT);
 
1223
 
 
1224
        return for_node;
 
1225
}
 
1226
 
 
1227
 
 
1228
static jrd_nod* par_field(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_operator)
 
1229
{
 
1230
/**************************************
 
1231
 *
 
1232
 *      p a r _ f i e l d
 
1233
 *
 
1234
 **************************************
 
1235
 *
 
1236
 * Functional description
 
1237
 *      Parse a field.
 
1238
 *
 
1239
 **************************************/
 
1240
        SET_TDBB(tdbb);
 
1241
 
 
1242
        const USHORT context = (unsigned int) BLR_BYTE;
 
1243
 
 
1244
        // check if this is a VALUE of domain's check constraint
 
1245
        if (!csb->csb_domain_validation.isEmpty() &&
 
1246
                (blr_operator == blr_fid || blr_operator == blr_field) &&
 
1247
                context == 0)
 
1248
        {
 
1249
                if (blr_operator == blr_fid) {
 
1250
                        SSHORT id = BLR_WORD;
 
1251
                        fb_assert(id == 0);
 
1252
                }
 
1253
                else {
 
1254
                        Firebird::MetaName name;
 
1255
                        par_name(csb, name);
 
1256
                }
 
1257
 
 
1258
                jrd_nod* node = PAR_make_node(tdbb, e_domval_length);
 
1259
                node->nod_type = nod_domain_validation;
 
1260
                node->nod_count = 0;
 
1261
 
 
1262
                dsc* desc = (dsc*) (node->nod_arg + e_domval_desc);
 
1263
                MET_get_domain(tdbb, csb->csb_domain_validation, desc, NULL);
 
1264
 
 
1265
                return node;
 
1266
        }
 
1267
 
 
1268
        if (context >= csb->csb_rpt.getCount())/* ||
 
1269
                !(csb->csb_rpt[context].csb_flags & csb_used) )
 
1270
 
 
1271
                dimitr: commented out to support system triggers implementing
 
1272
                                WITH CHECK OPTION. They reference the relation stream (#2)
 
1273
                                directly, without a DSQL context. It breaks the layering,
 
1274
                                but we must support legacy BLR.
 
1275
                */
 
1276
        {
 
1277
                error(csb, isc_ctxnotdef, 0);
 
1278
        }
 
1279
 
 
1280
        Firebird::MetaName name;
 
1281
        SSHORT id;
 
1282
        const SSHORT stream = csb->csb_rpt[context].csb_stream;
 
1283
        SSHORT flags = 0;
 
1284
        bool is_column = false;
 
1285
 
 
1286
        if (blr_operator == blr_fid)
 
1287
        {
 
1288
                id = BLR_WORD;
 
1289
                flags = nod_id;
 
1290
                is_column = true;
 
1291
        }
 
1292
        else if (blr_operator == blr_field)
 
1293
        {
 
1294
                CompilerScratch::csb_repeat* tail = &csb->csb_rpt[stream];
 
1295
                const jrd_prc* procedure = tail->csb_procedure;
 
1296
 
 
1297
                /* make sure procedure has been scanned before using it */
 
1298
 
 
1299
                if (procedure && (!(procedure->prc_flags & PRC_scanned)
 
1300
                                                  || (procedure->prc_flags & PRC_being_scanned)
 
1301
                                                  || (procedure->prc_flags & PRC_being_altered)))
 
1302
                {
 
1303
                        const jrd_prc* scan_proc = MET_procedure(tdbb, procedure->prc_id, false, 0);
 
1304
                        if (scan_proc != procedure)
 
1305
                                procedure = NULL;
 
1306
                }
 
1307
 
 
1308
                if (procedure) {
 
1309
                        par_name(csb, name);
 
1310
                        if ((id = find_proc_field(procedure, name)) == -1)
 
1311
                                error(csb,
 
1312
                                          isc_fldnotdef2,
 
1313
                                          isc_arg_string, ERR_cstring(name),
 
1314
                                          isc_arg_string, procedure->prc_name.c_str(), 0);
 
1315
                }
 
1316
                else {
 
1317
                        jrd_rel* relation = tail->csb_relation;
 
1318
                        if (!relation)
 
1319
                                error(csb, isc_ctxnotdef, 0);
 
1320
 
 
1321
                        /* make sure relation has been scanned before using it */
 
1322
 
 
1323
                        if (!(relation->rel_flags & REL_scanned) ||
 
1324
                                (relation->rel_flags & REL_being_scanned))
 
1325
                        {
 
1326
                                        MET_scan_relation(tdbb, relation);
 
1327
                        }
 
1328
 
 
1329
                        par_name(csb, name);
 
1330
                        if ((id = MET_lookup_field(tdbb, relation, name.c_str(), 0)) < 0) {
 
1331
                                if (csb->csb_g_flags & csb_validation) {
 
1332
                                        id = 0;
 
1333
                                        flags |= nod_id;
 
1334
                                        is_column = true;
 
1335
                                }
 
1336
                                else {
 
1337
                                        if (tdbb->getAttachment()->att_flags & ATT_gbak_attachment)
 
1338
                                        {
 
1339
                                                warning(csb, isc_fldnotdef, isc_arg_string,
 
1340
                                                                ERR_cstring(name), isc_arg_string,
 
1341
                                                                relation->rel_name.c_str(), 0);
 
1342
                                        }
 
1343
                                        else if (relation->rel_name.length() > 0)
 
1344
                                        {
 
1345
                                                error(csb, isc_fldnotdef, isc_arg_string,
 
1346
                                                          ERR_cstring(name), isc_arg_string,
 
1347
                                                          relation->rel_name.c_str(), 0);
 
1348
                                        }
 
1349
                                        else
 
1350
                                                error(csb, isc_ctxnotdef, 0);
 
1351
                                }
 
1352
                        }
 
1353
                }
 
1354
        }
 
1355
 
 
1356
/* check for dependencies -- if a field name was given,
 
1357
   use it because when restoring the database the field
 
1358
   id's may not be valid yet */
 
1359
 
 
1360
        if (csb->csb_g_flags & csb_get_dependencies) {
 
1361
                if (blr_operator == blr_fid)
 
1362
                        par_dependency(tdbb, csb, stream, id, "");
 
1363
                else
 
1364
                        par_dependency(tdbb, csb, stream, id, name);
 
1365
        }
 
1366
 
 
1367
        jrd_nod* node = PAR_gen_field(tdbb, stream, id);
 
1368
        node->nod_flags |= flags;
 
1369
 
 
1370
        if (is_column)
 
1371
        {
 
1372
                jrd_rel* temp_rel = csb->csb_rpt[stream].csb_relation;
 
1373
 
 
1374
                if (temp_rel)
 
1375
                {
 
1376
                        jrd_fld* field;
 
1377
 
 
1378
                        if (id < (int) temp_rel->rel_fields->count() && (field = (*temp_rel->rel_fields)[id]))
 
1379
                        {
 
1380
                                if (field->fld_default_value && field->fld_not_null)
 
1381
                                        node->nod_arg[e_fld_default_value] = field->fld_default_value;
 
1382
                        }
 
1383
                        else
 
1384
                        {
 
1385
                                if (temp_rel->rel_flags & REL_system)
 
1386
                                {
 
1387
                                        node = PAR_make_node(tdbb, 0);
 
1388
                                        node->nod_type = nod_null;
 
1389
                                }
 
1390
                        }
 
1391
                }
 
1392
        }
 
1393
 
 
1394
        return node;
 
1395
}
 
1396
 
 
1397
 
 
1398
static jrd_nod* par_function(thread_db* tdbb, CompilerScratch* csb)
 
1399
{
 
1400
/**************************************
 
1401
 *
 
1402
 *      p a r _ f u n c t i o n
 
1403
 *
 
1404
 **************************************
 
1405
 *
 
1406
 * Functional description
 
1407
 *      Parse a function reference.
 
1408
 *
 
1409
 **************************************/
 
1410
        SET_TDBB(tdbb);
 
1411
        
 
1412
        Firebird::MetaName name;
 
1413
        const USHORT count = par_name(csb, name);
 
1414
 
 
1415
        UserFunction* function = FUN_lookup_function(name,
 
1416
                                        !(tdbb->getAttachment()->att_flags & ATT_gbak_attachment));
 
1417
        if (!function) {
 
1418
                if (tdbb->tdbb_flags & TDBB_prc_being_dropped) {
 
1419
                        jrd_nod* anode = PAR_make_node(tdbb, e_fun_length);
 
1420
                        anode->nod_count = 1;
 
1421
                        anode->nod_arg[e_fun_function] = NULL;
 
1422
                        anode->nod_arg[e_fun_args] = par_args(tdbb, csb, VALUE);
 
1423
                        return anode;
 
1424
                }
 
1425
                else {
 
1426
                        csb->csb_running -= count;
 
1427
                        error(csb, isc_funnotdef, isc_arg_string, ERR_cstring(name), 0);
 
1428
                }
 
1429
        }
 
1430
 
 
1431
        UserFunction* homonyms;
 
1432
        for (homonyms = function; homonyms; homonyms = homonyms->fun_homonym) {
 
1433
                if (homonyms->fun_entrypoint)
 
1434
                        break;
 
1435
        }
 
1436
 
 
1437
        if (!homonyms)
 
1438
                if (tdbb->getAttachment()->att_flags & ATT_gbak_attachment)
 
1439
                {
 
1440
                        warning(csb, isc_funnotdef,
 
1441
                                        isc_arg_string, ERR_cstring(name),
 
1442
                                        isc_arg_interpreted,
 
1443
                                        "module name or entrypoint could not be found", 0);
 
1444
                }
 
1445
                else {
 
1446
                        csb->csb_running -= count;
 
1447
                        error(csb, isc_funnotdef,
 
1448
                                  isc_arg_string, ERR_cstring(name),
 
1449
                                  isc_arg_interpreted,
 
1450
                                  "module name or entrypoint could not be found", 0);
 
1451
                }
 
1452
 
 
1453
        jrd_nod* node = PAR_make_node(tdbb, e_fun_length);
 
1454
        node->nod_count = 1;
 
1455
        node->nod_arg[e_fun_function] = (jrd_nod*) function;
 
1456
        node->nod_arg[e_fun_args] = par_args(tdbb, csb, VALUE);
 
1457
 
 
1458
    /* CVC: I will track ufds only if a proc is not being dropped. */
 
1459
    if (csb->csb_g_flags & csb_get_dependencies) {
 
1460
        jrd_nod* dep_node = PAR_make_node (tdbb, e_dep_length);
 
1461
        dep_node->nod_type = nod_dependency;
 
1462
        dep_node->nod_arg [e_dep_object] = (jrd_nod*) function;
 
1463
        dep_node->nod_arg [e_dep_object_type] = (jrd_nod*)(IPTR) obj_udf;
 
1464
        csb->csb_dependencies.push(dep_node);
 
1465
    }
 
1466
 
 
1467
        return node;
 
1468
}
 
1469
 
 
1470
 
 
1471
static jrd_nod* par_literal(thread_db* tdbb, CompilerScratch* csb)
 
1472
{
 
1473
/**************************************
 
1474
 *
 
1475
 *      p a r _ l i t e r a l
 
1476
 *
 
1477
 **************************************
 
1478
 *
 
1479
 * Functional description
 
1480
 *      Parse a literal value.
 
1481
 *
 
1482
 **************************************/
 
1483
        SSHORT scale;
 
1484
        UCHAR dtype;
 
1485
 
 
1486
        SET_TDBB(tdbb);
 
1487
 
 
1488
        DSC desc;
 
1489
        PAR_desc(tdbb, csb, &desc);
 
1490
        const int count = lit_delta +
 
1491
                (desc.dsc_length + sizeof(jrd_nod*) - 1) / sizeof(jrd_nod*);
 
1492
        jrd_nod* node = PAR_make_node(tdbb, count);
 
1493
        Literal* literal = (Literal*) node;
 
1494
        node->nod_count = 0;
 
1495
        literal->lit_desc = desc;
 
1496
        UCHAR* p = reinterpret_cast<UCHAR*>(literal->lit_data);
 
1497
        literal->lit_desc.dsc_address = p;
 
1498
        literal->lit_desc.dsc_flags = 0;
 
1499
        const UCHAR* q = csb->csb_running;
 
1500
        USHORT l = desc.dsc_length;
 
1501
 
 
1502
        switch (desc.dsc_dtype) {
 
1503
        case dtype_short:
 
1504
                l = 2;
 
1505
                *(SSHORT *) p = (SSHORT) gds__vax_integer(q, l);
 
1506
                break;
 
1507
 
 
1508
        case dtype_long:
 
1509
        case dtype_sql_date:
 
1510
        case dtype_sql_time:
 
1511
                l = 4;
 
1512
                *(SLONG *) p = gds__vax_integer(q, l);
 
1513
                break;
 
1514
 
 
1515
        case dtype_timestamp:
 
1516
                l = 8;
 
1517
                *(SLONG *) p = gds__vax_integer(q, 4);
 
1518
                p += 4;
 
1519
                q += 4;
 
1520
                *(SLONG *) p = gds__vax_integer(q, 4);
 
1521
                break;
 
1522
 
 
1523
        case dtype_int64:
 
1524
                l = sizeof(SINT64);
 
1525
                *(SINT64 *) p = isc_portable_integer(q, l);
 
1526
                break;
 
1527
 
 
1528
        case dtype_double:
 
1529
                /* the double literal could potentially be used for any
 
1530
                   numeric literal - the value is passed as if it were a
 
1531
                   text string. Convert the numeric string to its binary
 
1532
                   value (int64, long or double as appropriate). */
 
1533
                l = BLR_WORD;
 
1534
                q = csb->csb_running;
 
1535
                dtype =
 
1536
                        CVT_get_numeric(q, l, &scale, (double *) p, ERR_post);
 
1537
                literal->lit_desc.dsc_dtype = dtype;
 
1538
                if (dtype == dtype_double)
 
1539
                        literal->lit_desc.dsc_length = sizeof(double);
 
1540
                else if (dtype == dtype_long) {
 
1541
                        literal->lit_desc.dsc_length = sizeof(SLONG);
 
1542
                        literal->lit_desc.dsc_scale = (SCHAR) scale;
 
1543
                }
 
1544
                else {
 
1545
                        literal->lit_desc.dsc_length = sizeof(SINT64);
 
1546
                        literal->lit_desc.dsc_scale = (SCHAR) scale;
 
1547
                }
 
1548
                break;
 
1549
 
 
1550
        case dtype_text:
 
1551
                memcpy(p, q, l);
 
1552
                break;
 
1553
 
 
1554
        default:
 
1555
                fb_assert(FALSE);
 
1556
        }
 
1557
 
 
1558
        csb->csb_running += l;
 
1559
 
 
1560
        return node;
 
1561
}
 
1562
 
 
1563
 
 
1564
static jrd_nod* par_map(thread_db* tdbb, CompilerScratch* csb, USHORT stream)
 
1565
{
 
1566
/**************************************
 
1567
 *
 
1568
 *      p a r _ m a p
 
1569
 *
 
1570
 **************************************
 
1571
 *
 
1572
 * Functional description
 
1573
 *      Parse a MAP clause for a union or global aggregate expression.
 
1574
 *
 
1575
 **************************************/
 
1576
        SET_TDBB(tdbb);
 
1577
 
 
1578
        if (BLR_BYTE != blr_map)
 
1579
                syntax_error(csb, "blr_map");
 
1580
 
 
1581
        SSHORT count = BLR_WORD;
 
1582
        NodeStack map;
 
1583
 
 
1584
        while (--count >= 0) {
 
1585
                jrd_nod* assignment = PAR_make_node(tdbb, e_asgn_length);
 
1586
                assignment->nod_type = nod_assignment;
 
1587
                assignment->nod_count = e_asgn_length;
 
1588
                assignment->nod_arg[e_asgn_to] =
 
1589
                        PAR_gen_field(tdbb, stream, BLR_WORD);
 
1590
                assignment->nod_arg[e_asgn_from] = parse(tdbb, csb, VALUE);
 
1591
                map.push(assignment);
 
1592
        }
 
1593
 
 
1594
        jrd_nod* node = PAR_make_list(tdbb, map);
 
1595
        node->nod_type = nod_map;
 
1596
 
 
1597
        return node;
 
1598
}
 
1599
 
 
1600
 
 
1601
static jrd_nod* par_message(thread_db* tdbb, CompilerScratch* csb)
 
1602
{
 
1603
/**************************************
 
1604
 *
 
1605
 *      p a r _ m e s s a g e
 
1606
 *
 
1607
 **************************************
 
1608
 *
 
1609
 * Functional description
 
1610
 *      Parse a message declaration, including operator byte.
 
1611
 *
 
1612
 **************************************/
 
1613
        SET_TDBB(tdbb);
 
1614
 
 
1615
/* Get message number, register it in the compiler scratch block, and
 
1616
   allocate a node to represent the message */
 
1617
 
 
1618
        USHORT n = (unsigned int) BLR_BYTE;
 
1619
        CompilerScratch::csb_repeat* tail = CMP_csb_element(csb, n);
 
1620
        jrd_nod* node = PAR_make_node(tdbb, e_msg_length);
 
1621
        tail->csb_message = node;
 
1622
        node->nod_count = 0;
 
1623
        node->nod_arg[e_msg_number] = (jrd_nod*) (IPTR) n;
 
1624
        if (n > csb->csb_msg_number)
 
1625
                csb->csb_msg_number = n;
 
1626
 
 
1627
/* Get the number of parameters in the message and prepare to fill
 
1628
   out the format block */
 
1629
 
 
1630
        n = BLR_WORD;
 
1631
        Format* format = Format::newFormat(*tdbb->getDefaultPool(), n);
 
1632
        node->nod_arg[e_msg_format] = (jrd_nod*) format;
 
1633
        ULONG offset = 0;
 
1634
 
 
1635
        Format::fmt_desc_iterator desc, end;
 
1636
        USHORT index = 0;
 
1637
 
 
1638
        for (desc = format->fmt_desc.begin(), end = desc + n; desc < end; ++desc, ++index)
 
1639
        {
 
1640
                ItemInfo itemInfo;
 
1641
                const USHORT alignment = PAR_desc(tdbb, csb, &*desc, &itemInfo);
 
1642
                if (alignment)
 
1643
                        offset = FB_ALIGN(offset, alignment);
 
1644
                desc->dsc_address = (UCHAR *) (IPTR) offset;
 
1645
                offset += desc->dsc_length;
 
1646
 
 
1647
                // ASF: Odd indexes are the nullable flag.
 
1648
                // So we only check even indexes, which is the actual parameter.
 
1649
                if (itemInfo.isSpecial() && index % 2 == 0)
 
1650
                {
 
1651
                        csb->csb_dbg_info.argInfoToName.get(
 
1652
                                Firebird::ArgumentInfo(csb->csb_msg_number, index / 2), itemInfo.name);
 
1653
 
 
1654
                        csb->csb_map_item_info.put(
 
1655
                                Item(nod_argument, csb->csb_msg_number, index), itemInfo);
 
1656
                }
 
1657
        }
 
1658
 
 
1659
        if (offset > MAX_FORMAT_SIZE)
 
1660
                error(csb, isc_imp_exc, isc_arg_gds, isc_blktoobig, 0);
 
1661
 
 
1662
        format->fmt_length = (USHORT) offset;
 
1663
 
 
1664
        return node;
 
1665
}
 
1666
 
 
1667
 
 
1668
static jrd_nod* par_modify(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_operator)
 
1669
{
 
1670
/**************************************
 
1671
 *
 
1672
 *      p a r _ m o d i f y
 
1673
 *
 
1674
 **************************************
 
1675
 *
 
1676
 * Functional description
 
1677
 *      Parse a modify statement.
 
1678
 *
 
1679
 **************************************/
 
1680
        SET_TDBB(tdbb);
 
1681
 
 
1682
/* Parse the original and new contexts */
 
1683
 
 
1684
        USHORT context = (unsigned int) BLR_BYTE;
 
1685
        if (context >= csb->csb_rpt.getCount() || 
 
1686
                !(csb->csb_rpt[context].csb_flags & csb_used))
 
1687
        {
 
1688
                error(csb, isc_ctxnotdef, 0);
 
1689
        }
 
1690
        const SSHORT org_stream = csb->csb_rpt[context].csb_stream;
 
1691
        const SSHORT new_stream = csb->nextStream(false);
 
1692
        if (new_stream >= MAX_STREAMS)
 
1693
        {
 
1694
                error(csb, isc_too_many_contexts, 0);
 
1695
        }
 
1696
        context = (unsigned int) BLR_BYTE;
 
1697
 
 
1698
/* Make sure the compiler scratch block is big enough to hold
 
1699
   everything */
 
1700
 
 
1701
        CompilerScratch::csb_repeat* tail = CMP_csb_element(csb, context);
 
1702
        tail->csb_stream = (UCHAR) new_stream;
 
1703
        tail->csb_flags |= csb_used;
 
1704
 
 
1705
        tail = CMP_csb_element(csb, new_stream);
 
1706
        tail->csb_relation = csb->csb_rpt[org_stream].csb_relation;
 
1707
 
 
1708
/* Make the node and parse the sub-expression */
 
1709
 
 
1710
        jrd_nod* node = PAR_make_node(tdbb, e_mod_length);
 
1711
        node->nod_count = 1;
 
1712
        node->nod_arg[e_mod_org_stream] = (jrd_nod*) (IPTR) org_stream;
 
1713
        node->nod_arg[e_mod_new_stream] = (jrd_nod*) (IPTR) new_stream;
 
1714
        node->nod_arg[e_mod_statement] = parse(tdbb, csb, STATEMENT);
 
1715
 
 
1716
        if (blr_operator == blr_modify2)
 
1717
        {
 
1718
                node->nod_count = 2;
 
1719
                node->nod_arg[e_mod_statement2] = parse(tdbb, csb, STATEMENT);
 
1720
        }
 
1721
 
 
1722
        return node;
 
1723
}
 
1724
 
 
1725
 
 
1726
static USHORT par_name(CompilerScratch* csb, Firebird::MetaName& name)
 
1727
{
 
1728
/**************************************
 
1729
 *
 
1730
 *      p a r _ n a m e
 
1731
 *
 
1732
 **************************************
 
1733
 *
 
1734
 * Functional description
 
1735
 *      Parse a counted string, returning count.
 
1736
 *
 
1737
 **************************************/
 
1738
        size_t l = BLR_BYTE;
 
1739
 
 
1740
        // Check for overly long identifiers at BLR parse stage to prevent unwanted
 
1741
        // surprises in deeper layers of the engine.
 
1742
        if (l > MAX_SQL_IDENTIFIER_LEN) {
 
1743
                SqlIdentifier st;
 
1744
                char* s = st;
 
1745
                l = MAX_SQL_IDENTIFIER_LEN;
 
1746
                while (l--) {
 
1747
                        *s++ = BLR_BYTE;
 
1748
                }
 
1749
                *s = 0;
 
1750
                ERR_post(isc_identifier_too_long, isc_arg_string, ERR_cstring(st), 0);
 
1751
        }
 
1752
 
 
1753
        char* s = name.getBuffer(l);
 
1754
 
 
1755
        while (l--) 
 
1756
        {
 
1757
                *s++ = BLR_BYTE;
 
1758
        }
 
1759
 
 
1760
        return name.length();
 
1761
}
 
1762
 
 
1763
 
 
1764
static size_t par_name(CompilerScratch* csb, Firebird::string& name)
 
1765
{
 
1766
/**************************************
 
1767
 *
 
1768
 *      p a r _ n a m e
 
1769
 *
 
1770
 **************************************
 
1771
 *
 
1772
 * Functional description
 
1773
 *      Parse a counted string of virtually unlimited size 
 
1774
 *  (up to 64K, actually <= 255), returning count.
 
1775
 *
 
1776
 **************************************/
 
1777
        size_t l = BLR_BYTE;
 
1778
        char* s = name.getBuffer(l);
 
1779
 
 
1780
        while (l--) 
 
1781
        {
 
1782
                *s++ = BLR_BYTE;
 
1783
        }
 
1784
 
 
1785
        return name.length();
 
1786
}
 
1787
 
 
1788
 
 
1789
static jrd_nod* par_plan(thread_db* tdbb, CompilerScratch* csb)
 
1790
{
 
1791
/**************************************
 
1792
 *
 
1793
 *      p a r _ p l a n
 
1794
 *
 
1795
 **************************************
 
1796
 *
 
1797
 * Functional description
 
1798
 *      Parse an access plan expression.  
 
1799
 *      At this stage we are just generating the 
 
1800
 *      parse tree and checking contexts 
 
1801
 *      and indices.
 
1802
 *
 
1803
 **************************************/
 
1804
        SET_TDBB(tdbb);
 
1805
 
 
1806
        USHORT node_type = (USHORT) BLR_BYTE;
 
1807
 
 
1808
/* a join type indicates a cross of two or more streams */
 
1809
 
 
1810
        if (node_type == blr_join || node_type == blr_merge) {
 
1811
                USHORT count = (USHORT) BLR_BYTE;
 
1812
                jrd_nod* plan = PAR_make_node(tdbb, count);
 
1813
                plan->nod_type = (NOD_T) (USHORT) blr_table[node_type];
 
1814
 
 
1815
                for (jrd_nod** arg = plan->nod_arg; count--;)
 
1816
                        *arg++ = par_plan(tdbb, csb);
 
1817
                return plan;
 
1818
        }
 
1819
 
 
1820
/* we have hit a stream; parse the context number and access type */
 
1821
 
 
1822
        if (node_type == blr_retrieve) {
 
1823
                jrd_nod* plan = PAR_make_node(tdbb, e_retrieve_length);
 
1824
                plan->nod_type = (NOD_T) (USHORT) blr_table[node_type];
 
1825
 
 
1826
                /* parse the relation name and context--the relation 
 
1827
                   itself is redundant except in the case of a view,
 
1828
                   in which case the base relation (and alias) must be specified */
 
1829
 
 
1830
                USHORT n = (unsigned int) BLR_BYTE;
 
1831
                if (n != blr_relation && n != blr_relation2 &&
 
1832
                        n != blr_rid && n != blr_rid2)
 
1833
                {
 
1834
                        syntax_error(csb, elements[RELATION]);
 
1835
                }
 
1836
 
 
1837
                /* don't have par_relation() parse the context, because
 
1838
                   this would add a new context; while this is a reference to 
 
1839
                   an existing context */
 
1840
 
 
1841
                jrd_nod* relation_node = par_relation(tdbb, csb, n, false);
 
1842
                plan->nod_arg[e_retrieve_relation] = relation_node;
 
1843
                jrd_rel* relation = (jrd_rel*) relation_node->nod_arg[e_rel_relation];
 
1844
 
 
1845
                n = BLR_BYTE;
 
1846
                if (n >= csb->csb_rpt.getCount() || !(csb->csb_rpt[n].csb_flags & csb_used))
 
1847
                        error(csb, isc_ctxnotdef, 0);
 
1848
                const SSHORT stream = csb->csb_rpt[n].csb_stream;
 
1849
 
 
1850
                relation_node->nod_arg[e_rel_stream] = (jrd_nod*) (IPTR) stream;
 
1851
                relation_node->nod_arg[e_rel_context] = (jrd_nod*) (IPTR) n;
 
1852
 
 
1853
                /* Access plan types (sequential is default) */
 
1854
 
 
1855
                node_type = (USHORT) BLR_BYTE;
 
1856
                USHORT extra_count = 0;
 
1857
                jrd_nod* access_type = 0;
 
1858
                Firebird::MetaName name;
 
1859
                TEXT* idx_name = 0;
 
1860
                
 
1861
                switch (node_type) {
 
1862
                case blr_navigational:
 
1863
                        {
 
1864
                                access_type = plan->nod_arg[e_retrieve_access_type] =
 
1865
                                        PAR_make_node(tdbb, e_access_type_length);
 
1866
                                access_type->nod_type = nod_navigational;
 
1867
 
 
1868
                                /* pick up the index name and look up the appropriate ids */
 
1869
 
 
1870
                                par_name(csb, name);
 
1871
                    /* CVC: We can't do this. Index names are identifiers.
 
1872
                       for (p = name; *p; *p++)
 
1873
                       *p = UPPER (*p);
 
1874
                       */
 
1875
                                SLONG relation_id;
 
1876
                                SSHORT idx_status;
 
1877
                                const SLONG index_id =
 
1878
                                        MET_lookup_index_name(tdbb, name, &relation_id, &idx_status);
 
1879
 
 
1880
                                if (idx_status == MET_object_unknown ||
 
1881
                                        idx_status == MET_object_inactive)
 
1882
                                {
 
1883
                                        if (tdbb->getAttachment()->att_flags & ATT_gbak_attachment)
 
1884
                                        {
 
1885
                                                warning(csb, isc_indexname, isc_arg_string,
 
1886
                                                                ERR_cstring(name), isc_arg_string,
 
1887
                                                                relation->rel_name.c_str(), 0);
 
1888
                                        }
 
1889
                                        else
 
1890
                                        {
 
1891
                                                error(csb, isc_indexname, isc_arg_string,
 
1892
                                                          ERR_cstring(name), isc_arg_string,
 
1893
                                                          relation->rel_name.c_str(), 0);
 
1894
                                        }
 
1895
                                }
 
1896
 
 
1897
                                /* save both the relation id and the index id, since
 
1898
                                   the relation could be a base relation of a view;
 
1899
                                   save the index name also, for convenience */
 
1900
 
 
1901
                                access_type->nod_arg[e_access_type_relation] = (jrd_nod*) (IPTR) relation_id;
 
1902
                                access_type->nod_arg[e_access_type_index] = (jrd_nod*) (IPTR) index_id;
 
1903
                                idx_name = stringDup(*tdbb->getDefaultPool(), name.c_str());
 
1904
                                access_type->nod_arg[e_access_type_index_name] = (jrd_nod*) idx_name;
 
1905
 
 
1906
                                if (csb->csb_g_flags & csb_get_dependencies)
 
1907
                                {
 
1908
                        jrd_nod* dep_node = PAR_make_node (tdbb, e_dep_length);
 
1909
                        dep_node->nod_type = nod_dependency;
 
1910
                        dep_node->nod_arg[e_dep_object] = (jrd_nod*) idx_name;
 
1911
                        dep_node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_index;
 
1912
                        csb->csb_dependencies.push(dep_node);
 
1913
                    }
 
1914
 
 
1915
                                if (BLR_PEEK == blr_indices)
 
1916
                                        // dimitr:      FALL INTO, if the plan item is ORDER ... INDEX (...)
 
1917
                                        extra_count = 3;
 
1918
                                else
 
1919
                                        break;
 
1920
                        }
 
1921
                case blr_indices:
 
1922
                        {
 
1923
                                if (extra_count)
 
1924
                                        BLR_BYTE; // skip blr_indices
 
1925
                                USHORT count = (USHORT) BLR_BYTE;
 
1926
                                jrd_nod* temp = plan->nod_arg[e_retrieve_access_type] =
 
1927
                                        PAR_make_node(tdbb, count * e_access_type_length + extra_count);
 
1928
                                for (USHORT i = 0; i < extra_count; i++) {
 
1929
                                        temp->nod_arg[i] = access_type->nod_arg[i];
 
1930
                                }
 
1931
                                temp->nod_type = (extra_count) ? nod_navigational : nod_indices;
 
1932
                                if (extra_count)
 
1933
                                        delete access_type;
 
1934
                                access_type = temp;
 
1935
 
 
1936
                                /* pick up the index names and look up the appropriate ids */
 
1937
 
 
1938
                                for (jrd_nod** arg = access_type->nod_arg + extra_count; count--;) {
 
1939
                                        par_name(csb, name);
 
1940
                                /* Nickolay Samofatov: We can't do this. Index names are identifiers.
 
1941
                                         for (p = name; *p; *p++)
 
1942
                                         *p = UPPER(*p);
 
1943
                             */
 
1944
                                        SLONG relation_id;
 
1945
                                        SSHORT idx_status;
 
1946
                                        const SLONG index_id =
 
1947
                                                MET_lookup_index_name(tdbb, name, &relation_id, &idx_status);
 
1948
 
 
1949
                                        if (idx_status == MET_object_unknown ||
 
1950
                                                idx_status == MET_object_inactive)
 
1951
                                        {
 
1952
                                                if (tdbb->getAttachment()->att_flags & ATT_gbak_attachment)
 
1953
                                                {
 
1954
                                                        warning(csb, isc_indexname, isc_arg_string,
 
1955
                                                                        ERR_cstring(name), isc_arg_string,
 
1956
                                                                        relation->rel_name.c_str(), 0);
 
1957
                                                }
 
1958
                                                else
 
1959
                                                {
 
1960
                                                        error(csb, isc_indexname, isc_arg_string,
 
1961
                                                                  ERR_cstring(name), isc_arg_string,
 
1962
                                                                  relation->rel_name.c_str(), 0);
 
1963
                                                }
 
1964
                                        }
 
1965
 
 
1966
                                        /* save both the relation id and the index id, since
 
1967
                                           the relation could be a base relation of a view;
 
1968
                                           save the index name also, for convenience */
 
1969
 
 
1970
                                        *arg++ = (jrd_nod*) (IPTR) relation_id;
 
1971
                                        *arg++ = (jrd_nod*) (IPTR) index_id;
 
1972
                                        idx_name = stringDup(*tdbb->getDefaultPool(), name.c_str());
 
1973
                                        *arg++ = (jrd_nod*) idx_name;
 
1974
 
 
1975
                                        if (csb->csb_g_flags & csb_get_dependencies)
 
1976
                                        {
 
1977
                                jrd_nod* dep_node = PAR_make_node (tdbb, e_dep_length);
 
1978
                                dep_node->nod_type = nod_dependency;
 
1979
                                dep_node->nod_arg[e_dep_object] = (jrd_nod*) idx_name;
 
1980
                                dep_node->nod_arg[e_dep_object_type] = (jrd_nod*)(IPTR) obj_index;
 
1981
                                csb->csb_dependencies.push(dep_node);
 
1982
                            }
 
1983
                                }
 
1984
                        }
 
1985
                        break;
 
1986
                case blr_sequential:
 
1987
                        break;
 
1988
                default:
 
1989
                        syntax_error(csb, "access type");
 
1990
                }
 
1991
 
 
1992
                return plan;
 
1993
        }
 
1994
 
 
1995
        syntax_error(csb, "plan item");
 
1996
        return NULL;                    /* Added to remove compiler warning */
 
1997
}
 
1998
 
 
1999
 
 
2000
static jrd_nod* par_procedure(thread_db* tdbb, CompilerScratch* csb, SSHORT blr_operator)
 
2001
{
 
2002
/**************************************
 
2003
 *
 
2004
 *      p a r _ p r o c e d u r e
 
2005
 *
 
2006
 **************************************
 
2007
 *
 
2008
 * Functional description
 
2009
 *      Parse an procedural view reference.
 
2010
 *
 
2011
 **************************************/
 
2012
        jrd_prc* procedure;
 
2013
 
 
2014
        SET_TDBB(tdbb);
 
2015
 
 
2016
        {
 
2017
                Firebird::MetaName name;
 
2018
 
 
2019
                if (blr_operator == blr_procedure) {
 
2020
                        par_name(csb, name);
 
2021
                        procedure = MET_lookup_procedure(tdbb, name, false);
 
2022
                }
 
2023
                else {
 
2024
                        const SSHORT pid = BLR_WORD;
 
2025
                        if (!(procedure = MET_lookup_procedure_id(tdbb, pid, false, false, 0)))
 
2026
                                name.printf("id %d", pid);
 
2027
                }
 
2028
                if (!procedure)
 
2029
                        error(csb, isc_prcnotdef, isc_arg_string, ERR_cstring(name), 0);
 
2030
        }
 
2031
 
 
2032
        if (procedure->prc_type == prc_executable)
 
2033
        {
 
2034
                error(csb, isc_illegal_prc_type,
 
2035
                          isc_arg_string, ERR_string(procedure->prc_name), 0);
 
2036
        }
 
2037
 
 
2038
        jrd_nod* node = PAR_make_node(tdbb, e_prc_length);
 
2039
        node->nod_type = nod_procedure;
 
2040
        node->nod_count = count_table[blr_procedure];
 
2041
        node->nod_arg[e_prc_procedure] = (jrd_nod*) (IPTR) procedure->prc_id;
 
2042
 
 
2043
        const USHORT stream = par_context(csb, 0);
 
2044
        node->nod_arg[e_prc_stream] = (jrd_nod*) (IPTR) stream;
 
2045
        csb->csb_rpt[stream].csb_procedure = procedure;
 
2046
 
 
2047
        par_procedure_parms(tdbb, csb, procedure, &node->nod_arg[e_prc_in_msg],
 
2048
                                                &node->nod_arg[e_prc_inputs], true);
 
2049
 
 
2050
        if (csb->csb_g_flags & csb_get_dependencies)
 
2051
                par_dependency(tdbb, csb, stream, (SSHORT) - 1, "");
 
2052
 
 
2053
        return node;
 
2054
}
 
2055
 
 
2056
 
 
2057
static void par_procedure_parms(
 
2058
                                                                thread_db* tdbb,
 
2059
                                                                CompilerScratch* csb,
 
2060
                                                                jrd_prc* procedure,
 
2061
                                                                jrd_nod** message_ptr,
 
2062
                                                                jrd_nod** parameter_ptr, bool input_flag)
 
2063
{
 
2064
/**************************************
 
2065
 *
 
2066
 *      p a r _ p r o c e d u r e _ p a r m s
 
2067
 *
 
2068
 **************************************
 
2069
 *
 
2070
 * Functional description
 
2071
 *      Parse some procedure parameters.
 
2072
 *
 
2073
 **************************************/
 
2074
        SET_TDBB(tdbb);
 
2075
        bool mismatch = false;
 
2076
        SLONG count = BLR_WORD;
 
2077
 
 
2078
/** Check to see if the parameter count matches **/
 
2079
        if (input_flag ? 
 
2080
                        (count < (procedure->prc_inputs - procedure->prc_defaults) ||
 
2081
                        (count > procedure->prc_inputs) ) : 
 
2082
                        (count != procedure->prc_outputs)) 
 
2083
        {
 
2084
        /** They don't match...Hmmm...Its OK if we were dropping the procedure **/
 
2085
                if (!(tdbb->tdbb_flags & TDBB_prc_being_dropped)) {
 
2086
                        error(csb,
 
2087
                                  input_flag ? isc_prcmismat : isc_prc_out_param_mismatch,
 
2088
                                  isc_arg_string,
 
2089
                                  ERR_cstring(procedure->prc_name.c_str()),
 
2090
                                  0);
 
2091
                }
 
2092
                else
 
2093
                        mismatch = true;
 
2094
        }
 
2095
 
 
2096
        if (count || input_flag && procedure->prc_defaults) {
 
2097
        /** We have a few parameters. Get on with creating the message block **/
 
2098
                USHORT n = ++csb->csb_msg_number;
 
2099
                if (n < 2)
 
2100
                        csb->csb_msg_number = n = 2;
 
2101
                CompilerScratch::csb_repeat* tail = CMP_csb_element(csb, n);
 
2102
                jrd_nod* message = PAR_make_node(tdbb, e_msg_length);
 
2103
                tail->csb_message = message;
 
2104
                message->nod_type = nod_message;
 
2105
                message->nod_count = count_table[blr_message];
 
2106
                *message_ptr = message;
 
2107
                message->nod_count = 0;
 
2108
                message->nod_arg[e_msg_number] = (jrd_nod*)(IPTR) n;
 
2109
                const Format* format =
 
2110
                        input_flag ? procedure->prc_input_fmt : procedure->prc_output_fmt;
 
2111
                /* dimitr: procedure (with its parameter formats) is allocated out of
 
2112
                                   its own pool (prc_request->req_pool) and can be freed during
 
2113
                                   the cache cleanup (MET_clear_cache). Since the current
 
2114
                                   tdbb default pool is different from the procedure's one,
 
2115
                                   it's dangerous to copy a pointer from one request to another.
 
2116
                                   As an experiment, I've decided to copy format by value
 
2117
                                   instead of copying the reference. Since Format structure
 
2118
                                   doesn't contain any pointers, it should be safe to use a
 
2119
                                   default assignment operator which does a simple byte copy.
 
2120
                                   This change fixes one serious bug in the current codebase.
 
2121
                                   I think that this situation can (and probably should) be
 
2122
                                   handled by the metadata cache (via incrementing prc_use_count)
 
2123
                                   to avoid unexpected cache cleanups, but that area is out of my
 
2124
                                   knowledge. So this fix should be considered a temporary solution.
 
2125
 
 
2126
                message->nod_arg[e_msg_format] = (jrd_nod*) format;
 
2127
                */
 
2128
                Format* fmt_copy = Format::newFormat(*tdbb->getDefaultPool(), format->fmt_count);
 
2129
                *fmt_copy = *format;
 
2130
                message->nod_arg[e_msg_format] = (jrd_nod*) fmt_copy;
 
2131
                /* --- end of fix --- */
 
2132
                if (!mismatch)
 
2133
                        n = format->fmt_count / 2;
 
2134
                else {
 
2135
                        /*  There was a parameter mismatch hence can't depend upon the format's
 
2136
                           fmt_count. Use count instead.
 
2137
                         */
 
2138
                        n = count;
 
2139
                }
 
2140
                jrd_nod* list = *parameter_ptr = PAR_make_node(tdbb, n);
 
2141
                list->nod_type = nod_list;
 
2142
                list->nod_count = n;
 
2143
                jrd_nod** ptr = list->nod_arg;
 
2144
                USHORT asgn_arg1, asgn_arg2;
 
2145
                if (input_flag) {
 
2146
                        asgn_arg1 = e_asgn_from;
 
2147
                        asgn_arg2 = e_asgn_to;
 
2148
                }
 
2149
                else {
 
2150
                        asgn_arg1 = e_asgn_to;
 
2151
                        asgn_arg2 = e_asgn_from;
 
2152
                }
 
2153
                for (USHORT i = 0; n; count--, n--) {
 
2154
                        jrd_nod* asgn = PAR_make_node(tdbb, e_asgn_length);
 
2155
                        *ptr++ = asgn;
 
2156
                        asgn->nod_type = nod_assignment;
 
2157
                        asgn->nod_count = count_table[blr_assignment];
 
2158
 
 
2159
                        // default value for parameter 
 
2160
                        if ((count <= 0) && input_flag) {
 
2161
                                Parameter* parameter =
 
2162
                                        (*procedure->prc_input_fields)[procedure->prc_inputs - n];
 
2163
                                asgn->nod_arg[asgn_arg1] = parameter->prm_default_value;
 
2164
                        }
 
2165
                        else {
 
2166
                                asgn->nod_arg[asgn_arg1] = parse(tdbb, csb, VALUE);
 
2167
                        }
 
2168
                        jrd_nod* prm = asgn->nod_arg[asgn_arg2] =
 
2169
                                PAR_make_node(tdbb, e_arg_length);
 
2170
                        prm->nod_type = nod_argument;
 
2171
                        prm->nod_count = 1;
 
2172
                        prm->nod_arg[e_arg_message] = message;
 
2173
                        prm->nod_arg[e_arg_number] = (jrd_nod*)(IPTR) i++;
 
2174
                        jrd_nod* prm_f = prm->nod_arg[e_arg_flag] =
 
2175
                                PAR_make_node(tdbb, e_arg_length);
 
2176
                        prm_f->nod_type = nod_argument;
 
2177
                        prm_f->nod_count = 0;
 
2178
                        prm_f->nod_arg[e_arg_message] = message;
 
2179
                        prm_f->nod_arg[e_arg_number] = (jrd_nod*)(IPTR) i++;
 
2180
                }
 
2181
        }
 
2182
        else if ((input_flag ? procedure->prc_inputs : procedure->prc_outputs) &&
 
2183
                         !mismatch)
 
2184
        {
 
2185
                error(csb,
 
2186
                          input_flag ? isc_prcmismat : isc_prc_out_param_mismatch,
 
2187
                          isc_arg_string,
 
2188
                          ERR_cstring(procedure->prc_name.c_str()),
 
2189
                          0);
 
2190
        }
 
2191
}
 
2192
 
 
2193
 
 
2194
static jrd_nod* par_relation(
 
2195
                                                thread_db* tdbb,
 
2196
                                                CompilerScratch* csb, SSHORT blr_operator, bool parse_context)
 
2197
{
 
2198
/**************************************
 
2199
 *
 
2200
 *      p a r _ r e l a t i o n
 
2201
 *
 
2202
 **************************************
 
2203
 *
 
2204
 * Functional description
 
2205
 *      Parse a relation reference.
 
2206
 *
 
2207
 **************************************/
 
2208
        Firebird::MetaName name;
 
2209
 
 
2210
        SET_TDBB(tdbb);
 
2211
 
 
2212
/* Make a relation reference node */
 
2213
 
 
2214
        jrd_nod* node = PAR_make_node(tdbb, e_rel_length);
 
2215
        node->nod_count = 0;
 
2216
 
 
2217
/* Find relation either by id or by name */
 
2218
        jrd_rel* relation = 0;
 
2219
        Firebird::string* alias_string = 0;
 
2220
        if (blr_operator == blr_rid || blr_operator == blr_rid2) {
 
2221
                const SSHORT id = BLR_WORD;
 
2222
                if (blr_operator == blr_rid2) {
 
2223
                        alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
 
2224
                        par_name(csb, *alias_string);
 
2225
                }
 
2226
                if (!(relation = MET_lookup_relation_id(tdbb, id, false))) {
 
2227
                        name.printf("id %d", id);
 
2228
                        error(csb, isc_relnotdef, isc_arg_string, ERR_cstring(name), 0);
 
2229
                }
 
2230
        }
 
2231
        else if (blr_operator == blr_relation || blr_operator == blr_relation2) {
 
2232
                par_name(csb, name);
 
2233
                if (blr_operator == blr_relation2) {
 
2234
                        alias_string = FB_NEW(csb->csb_pool) Firebird::string(csb->csb_pool);
 
2235
                        par_name(csb, *alias_string);
 
2236
                }
 
2237
                if (!(relation = MET_lookup_relation(tdbb, name)))
 
2238
                        error(csb, isc_relnotdef, isc_arg_string, ERR_cstring(name), 0);
 
2239
        }
 
2240
 
 
2241
/* if an alias was passed, store with the relation */
 
2242
 
 
2243
        if (alias_string)
 
2244
        {
 
2245
                node->nod_arg[e_rel_alias] = 
 
2246
                        (jrd_nod*) stringDup(*tdbb->getDefaultPool(), alias_string->c_str());
 
2247
        }
 
2248
 
 
2249
/* Scan the relation if it hasn't already been scanned for meta data */
 
2250
 
 
2251
        if ((!(relation->rel_flags & REL_scanned)
 
2252
                 || (relation->rel_flags & REL_being_scanned))
 
2253
                && ((relation->rel_flags & REL_force_scan)
 
2254
                        || !(csb->csb_g_flags & csb_internal)))
 
2255
        {
 
2256
                relation->rel_flags &= ~REL_force_scan;
 
2257
                MET_scan_relation(tdbb, relation);
 
2258
        }
 
2259
        else if (relation->rel_flags & REL_sys_triggers)
 
2260
        {
 
2261
                MET_parse_sys_trigger(tdbb, relation);
 
2262
        }
 
2263
 
 
2264
/* generate a stream for the relation reference, 
 
2265
   assuming it is a real reference */
 
2266
 
 
2267
        if (parse_context) {
 
2268
                SSHORT context;
 
2269
                const SSHORT stream = par_context(csb, &context);
 
2270
                fb_assert(stream <= MAX_STREAMS);
 
2271
                node->nod_arg[e_rel_stream] = (jrd_nod*) (IPTR) stream;
 
2272
                node->nod_arg[e_rel_context] = (jrd_nod*) (IPTR) context;
 
2273
 
 
2274
                csb->csb_rpt[stream].csb_relation = relation;
 
2275
                csb->csb_rpt[stream].csb_alias = alias_string;
 
2276
 
 
2277
                if (csb->csb_g_flags & csb_get_dependencies)
 
2278
                        par_dependency(tdbb, csb, stream, (SSHORT) -1, "");
 
2279
        }
 
2280
        else
 
2281
        {
 
2282
                delete alias_string;
 
2283
        }
 
2284
 
 
2285
        node->nod_arg[e_rel_relation] = (jrd_nod*) relation;
 
2286
 
 
2287
        return node;
 
2288
}
 
2289
 
 
2290
 
 
2291
static jrd_nod* par_rse(thread_db* tdbb, CompilerScratch* csb, SSHORT rse_op)
 
2292
{
 
2293
/**************************************
 
2294
 *
 
2295
 *      p a r _ r s e
 
2296
 *
 
2297
 **************************************
 
2298
 *
 
2299
 * Functional description
 
2300
 *      Parse a record selection expression.
 
2301
 *
 
2302
 **************************************/
 
2303
        SET_TDBB(tdbb);
 
2304
 
 
2305
        SSHORT count = (unsigned int) BLR_BYTE;
 
2306
        RecordSelExpr* rse = (RecordSelExpr*) PAR_make_node(tdbb, count + rse_delta + 2);
 
2307
        rse->nod_count = 0;
 
2308
        rse->rse_count = count;
 
2309
        jrd_nod** ptr = rse->rse_relation;
 
2310
 
 
2311
        while (--count >= 0) {
 
2312
                // AB: Added TYPE_RSE for derived table support
 
2313
                *ptr++ = parse(tdbb, csb, RELATION, TYPE_RSE);
 
2314
                //*ptr++ = parse(tdbb, csb, RELATION);
 
2315
        }
 
2316
 
 
2317
        while (true) {
 
2318
                const UCHAR op = BLR_BYTE;
 
2319
                switch (op) {
 
2320
                case blr_boolean:
 
2321
                        rse->rse_boolean = parse(tdbb, csb, TYPE_BOOL);
 
2322
                        break;
 
2323
 
 
2324
                case blr_first:
 
2325
                        if (rse_op == blr_rs_stream)
 
2326
                                syntax_error(csb, "RecordSelExpr stream clause");
 
2327
                        rse->rse_first = parse(tdbb, csb, VALUE);
 
2328
                        break;
 
2329
 
 
2330
        case blr_skip:
 
2331
            if (rse_op == blr_rs_stream)
 
2332
                syntax_error (csb, "RecordSelExpr stream clause");
 
2333
            rse->rse_skip = parse (tdbb, csb, VALUE);
 
2334
            break;
 
2335
 
 
2336
                case blr_sort:
 
2337
                        if (rse_op == blr_rs_stream)
 
2338
                                syntax_error(csb, "RecordSelExpr stream clause");
 
2339
                        rse->rse_sorted = par_sort(tdbb, csb, true);
 
2340
                        break;
 
2341
 
 
2342
                case blr_project:
 
2343
                        if (rse_op == blr_rs_stream)
 
2344
                                syntax_error(csb, "RecordSelExpr stream clause");
 
2345
                        rse->rse_projection = par_sort(tdbb, csb, false);
 
2346
                        break;
 
2347
 
 
2348
                case blr_join_type:
 
2349
                        {
 
2350
                                const USHORT jointype = (USHORT) BLR_BYTE;
 
2351
                                rse->rse_jointype = jointype;
 
2352
                                if (jointype != blr_inner
 
2353
                                        && jointype != blr_left && jointype != blr_right
 
2354
                                        && jointype != blr_full)
 
2355
                                {
 
2356
                                        syntax_error(csb, "join type clause");
 
2357
                                }
 
2358
                                break;
 
2359
                        }
 
2360
 
 
2361
                case blr_plan:
 
2362
                        rse->rse_plan = par_plan(tdbb, csb);
 
2363
                        break;
 
2364
                        
 
2365
                case blr_writelock:
 
2366
                        rse->rse_writelock = true;
 
2367
                        break;
 
2368
 
 
2369
#ifdef SCROLLABLE_CURSORS
 
2370
                        /* if a receive is seen here, then it is intended to be an asynchronous 
 
2371
                           receive which can happen at any time during the scope of the RecordSelExpr-- 
 
2372
                           this is intended to be a more efficient mechanism for scrolling through 
 
2373
                           a record stream, to prevent having to send a message to the engine 
 
2374
                           for each record */
 
2375
 
 
2376
                case blr_receive:
 
2377
                        BLR_PUSH;
 
2378
                        rse->rse_async_message = parse(tdbb, csb, STATEMENT);
 
2379
                        break;
 
2380
#endif
 
2381
 
 
2382
                default:
 
2383
                        if (op == (UCHAR) blr_end) {
 
2384
                                /* An outer join is only allowed when the stream count is 2
 
2385
                                   and a boolean expression has been supplied */
 
2386
 
 
2387
                                if (!rse->rse_jointype ||
 
2388
                                        (rse->rse_count == 2 && rse->rse_boolean))
 
2389
                                {
 
2390
                                                // Convert right outer joins to left joins to avoid
 
2391
                                                // RIGHT JOIN handling at lower engine levels
 
2392
                                                if (rse->rse_jointype == blr_right) {
 
2393
                                                        // Swap sub-streams
 
2394
                                                        jrd_nod* temp = rse->rse_relation[0];
 
2395
                                                        rse->rse_relation[0] = rse->rse_relation[1];
 
2396
                                                        rse->rse_relation[1] = temp;
 
2397
 
 
2398
                                                        rse->rse_jointype = blr_left;
 
2399
                                                }
 
2400
                                                return (jrd_nod*) rse;
 
2401
                                }
 
2402
                        }
 
2403
                        syntax_error(csb, (TEXT*)((rse_op == blr_rs_stream) ?
 
2404
                                                 "RecordSelExpr stream clause" :
 
2405
                                                 "record selection expression clause"));
 
2406
                }
 
2407
        }
 
2408
}
 
2409
 
 
2410
 
 
2411
static jrd_nod* par_sort(thread_db* tdbb, CompilerScratch* csb, bool flag)
 
2412
{
 
2413
/**************************************
 
2414
 *
 
2415
 *      p a r _ s o r t
 
2416
 *
 
2417
 **************************************
 
2418
 *
 
2419
 * Functional description
 
2420
 *      Parse a sort clause (sans header byte).  This is used for
 
2421
 *      BLR_SORT, BLR_PROJECT, and BLR_GROUP.
 
2422
 *
 
2423
 **************************************/
 
2424
        SET_TDBB(tdbb);
 
2425
 
 
2426
        SSHORT count = (unsigned int) BLR_BYTE;
 
2427
        jrd_nod* clause = PAR_make_node(tdbb, count * 3);
 
2428
        clause->nod_type = nod_sort;
 
2429
        clause->nod_count = count;
 
2430
        jrd_nod** ptr = clause->nod_arg;
 
2431
        jrd_nod** ptr2 = ptr + count;
 
2432
        jrd_nod** ptr3 = ptr2 + count;
 
2433
 
 
2434
        while (--count >= 0) {
 
2435
                if (flag) {
 
2436
                        UCHAR code = BLR_BYTE;
 
2437
                        switch (code) {
 
2438
                        case blr_nullsfirst:
 
2439
                                *ptr3++ = (jrd_nod*) (IPTR) rse_nulls_first;
 
2440
                                code = BLR_BYTE;
 
2441
                                break;
 
2442
                        case blr_nullslast:
 
2443
                                *ptr3++ = (jrd_nod*) (IPTR) rse_nulls_last;
 
2444
                                code = BLR_BYTE;
 
2445
                                break;
 
2446
                        default:
 
2447
                                *ptr3++ = (jrd_nod*) (IPTR) rse_nulls_default;
 
2448
                        }
 
2449
                          
 
2450
                        *ptr2++ =
 
2451
                                (jrd_nod*) (IPTR) ((code == blr_descending) ? TRUE : FALSE);
 
2452
                }
 
2453
                *ptr++ = parse(tdbb, csb, VALUE);
 
2454
        }
 
2455
 
 
2456
        return clause;
 
2457
}
 
2458
 
 
2459
 
 
2460
#ifdef NOT_USED_OR_REPLACED
 
2461
static jrd_nod* par_stream(thread_db* tdbb, CompilerScratch* csb)
 
2462
{
 
2463
/**************************************
 
2464
 *
 
2465
 *      p a r _ s t r e a m
 
2466
 *
 
2467
 **************************************
 
2468
 *
 
2469
 * Functional description
 
2470
 *      Parse a stream expression.
 
2471
 *
 
2472
 **************************************/
 
2473
        SET_TDBB(tdbb);
 
2474
 
 
2475
        RecordSelExpr* rse = (RecordSelExpr*) PAR_make_node(tdbb, 1 + rse_delta + 2);
 
2476
        rse->nod_count = 0;
 
2477
        rse->rse_count = 1;
 
2478
        rse->rse_relation[0] = parse(tdbb, csb, RELATION);
 
2479
 
 
2480
        while (true) {
 
2481
                const UCHAR op = BLR_BYTE;
 
2482
                switch (op) {
 
2483
                case blr_boolean:
 
2484
                        rse->rse_boolean = parse(tdbb, csb, TYPE_BOOL);
 
2485
                        break;
 
2486
 
 
2487
                default:
 
2488
                        if (op == (UCHAR) blr_end)
 
2489
                                return (jrd_nod*) rse;
 
2490
                        syntax_error(csb, "stream_clause");
 
2491
                }
 
2492
        }
 
2493
}
 
2494
#endif
 
2495
 
 
2496
 
 
2497
static jrd_nod* par_sys_function(thread_db* tdbb, CompilerScratch* csb)
 
2498
{
 
2499
/**************************************
 
2500
 *
 
2501
 *      p a r _ s y s _ f u n c t i o n
 
2502
 *
 
2503
 **************************************
 
2504
 *
 
2505
 * Functional description
 
2506
 *      Parse a system function reference.
 
2507
 *
 
2508
 **************************************/
 
2509
        SET_TDBB(tdbb);
 
2510
        
 
2511
        Firebird::MetaName name;
 
2512
        const USHORT count = par_name(csb, name);
 
2513
 
 
2514
        const SysFunction* function = SysFunction::lookup(name);
 
2515
 
 
2516
        if (!function)
 
2517
        {
 
2518
                csb->csb_running -= count;
 
2519
                error(csb, isc_funnotdef, isc_arg_string, ERR_cstring(name), 0);
 
2520
        }
 
2521
 
 
2522
        jrd_nod* node = PAR_make_node(tdbb, e_sysfun_length);
 
2523
        node->nod_count = count_table[blr_sys_function];
 
2524
        node->nod_arg[e_sysfun_args] = par_args(tdbb, csb, VALUE);
 
2525
        node->nod_arg[e_sysfun_function] = (jrd_nod*) function;
 
2526
 
 
2527
        return node;
 
2528
}
 
2529
 
 
2530
 
 
2531
static jrd_nod* par_union(thread_db* tdbb, CompilerScratch* csb, bool recursive)
 
2532
{
 
2533
/**************************************
 
2534
 *
 
2535
 *      p a r _ u n i o n
 
2536
 *
 
2537
 **************************************
 
2538
 *
 
2539
 * Functional description
 
2540
 *      Parse a union reference.
 
2541
 *
 
2542
 **************************************/
 
2543
        SET_TDBB(tdbb);
 
2544
 
 
2545
/* Make the node, parse the context number, get a stream assigned,
 
2546
   and get the number of sub-RecordSelExpr's. */
 
2547
 
 
2548
        jrd_nod* node = PAR_make_node(tdbb, e_uni_length);
 
2549
        node->nod_count = 3;
 
2550
        const USHORT stream = par_context(csb, 0);
 
2551
        node->nod_arg[e_uni_stream] = (jrd_nod*) (IPTR) stream;
 
2552
 
 
2553
        // assign separate context for mapped record if union is recursive
 
2554
        USHORT map_stream = stream;
 
2555
        if (recursive)
 
2556
        {
 
2557
                node->nod_flags |= nod_recurse;
 
2558
                map_stream = par_context(csb, 0);
 
2559
                node->nod_arg[e_uni_map_stream] = (jrd_nod*) (IPTR) map_stream;
 
2560
        }
 
2561
 
 
2562
        SSHORT count = (unsigned int) BLR_BYTE;
 
2563
 
 
2564
/* Pick up the sub-RecordSelExpr's and maps */
 
2565
 
 
2566
        NodeStack clauses;
 
2567
 
 
2568
        while (--count >= 0) {
 
2569
                clauses.push(parse(tdbb, csb, TYPE_RSE));
 
2570
                clauses.push(par_map(tdbb, csb, map_stream));
 
2571
        }
 
2572
 
 
2573
        node->nod_arg[e_uni_clauses] = PAR_make_list(tdbb, clauses);
 
2574
 
 
2575
        return node;
 
2576
}
 
2577
 
 
2578
 
 
2579
static USHORT par_word(CompilerScratch* csb)
 
2580
{
 
2581
/**************************************
 
2582
 *
 
2583
 *      p a r _ w o r d
 
2584
 *
 
2585
 **************************************
 
2586
 *
 
2587
 * Functional description
 
2588
 *      Pick up a BLR word.
 
2589
 *
 
2590
 **************************************/
 
2591
        const UCHAR low = BLR_BYTE;
 
2592
        const UCHAR high = BLR_BYTE;
 
2593
 
 
2594
        return high * 256 + low;
 
2595
}
 
2596
 
 
2597
 
 
2598
static jrd_nod* parse(thread_db* tdbb, CompilerScratch* csb, USHORT expected,
 
2599
        USHORT expected_optional)
 
2600
{
 
2601
/**************************************
 
2602
 *
 
2603
 *      p a r s e
 
2604
 *
 
2605
 **************************************
 
2606
 *
 
2607
 * Functional description
 
2608
 *      Parse a BLR expression.
 
2609
 *
 
2610
 **************************************/
 
2611
        SET_TDBB(tdbb);
 
2612
 
 
2613
        const USHORT blr_offset = csb->csb_running - csb->csb_blr;
 
2614
        const SSHORT blr_operator = BLR_BYTE;
 
2615
 
 
2616
        if (blr_operator < 0 || blr_operator >= FB_NELEM(type_table)) {
 
2617
        // NS: This error string is correct, please do not mangle it again and again.
 
2618
                // The whole error message is "BLR syntax error: expected %s at offset %d, encountered %d"
 
2619
        syntax_error(csb, "valid BLR code");
 
2620
    }
 
2621
 
 
2622
        const SSHORT sub_type = sub_type_table[blr_operator];
 
2623
 
 
2624
        if (expected && (expected != type_table[blr_operator])) {
 
2625
                if (expected_optional) {
 
2626
                        if (expected_optional != type_table[blr_operator]) {
 
2627
                                syntax_error(csb, elements[expected]);
 
2628
                        }
 
2629
                }
 
2630
                else {
 
2631
                        syntax_error(csb, elements[expected]);
 
2632
                }
 
2633
        }
 
2634
 
 
2635
/* If there is a length given in the length table, pre-allocate
 
2636
   the node and set its count.  This saves an enormous amount of
 
2637
   repetitive code. */
 
2638
 
 
2639
        jrd_nod* node;
 
2640
        jrd_nod** arg;
 
2641
        USHORT n = length_table[blr_operator];
 
2642
        if (n) {
 
2643
                node = PAR_make_node(tdbb, n);
 
2644
                node->nod_count = count_table[blr_operator];
 
2645
                arg = node->nod_arg;
 
2646
        }
 
2647
        else {
 
2648
                node = NULL;
 
2649
                arg = NULL;
 
2650
        }
 
2651
 
 
2652
        bool set_type = true;
 
2653
 
 
2654
/* Dispatch on operator type. */
 
2655
 
 
2656
        switch (blr_operator) {
 
2657
        case blr_any:
 
2658
        case blr_unique:
 
2659
        case blr_ansi_any:
 
2660
        case blr_ansi_all:
 
2661
        case blr_exists:
 
2662
                node->nod_arg[e_any_rse] = parse(tdbb, csb, sub_type);
 
2663
                break;
 
2664
 
 
2665
                /* Boring operators -- no special handling req'd */
 
2666
 
 
2667
        case blr_value_if:
 
2668
        case blr_substring:
 
2669
        case blr_matching2:
 
2670
        case blr_ansi_like:
 
2671
                *arg++ = parse(tdbb, csb, sub_type);
 
2672
                *arg++ = parse(tdbb, csb, sub_type);
 
2673
                *arg++ = parse(tdbb, csb, sub_type);
 
2674
                break;
 
2675
 
 
2676
        case blr_trim:
 
2677
        {
 
2678
                node->nod_count = e_trim_count;
 
2679
                node->nod_arg[e_trim_specification] = (jrd_nod*)(U_IPTR) BLR_BYTE;
 
2680
 
 
2681
                BYTE trimWhat = BLR_BYTE;
 
2682
 
 
2683
                if (trimWhat == blr_trim_characters)
 
2684
                        node->nod_arg[e_trim_characters] = parse(tdbb, csb, sub_type);
 
2685
                else
 
2686
                {
 
2687
                        node->nod_arg[e_trim_characters] = NULL;
 
2688
                        --node->nod_count;
 
2689
                }
 
2690
 
 
2691
                node->nod_arg[e_trim_value] = parse(tdbb, csb, sub_type);
 
2692
                break;
 
2693
        }
 
2694
 
 
2695
        case blr_and:
 
2696
        case blr_or:
 
2697
 
 
2698
        case blr_prot_mask:
 
2699
        case blr_containing:
 
2700
        case blr_matching:
 
2701
        case blr_like:
 
2702
        case blr_starting:
 
2703
        case blr_add:
 
2704
        case blr_subtract:
 
2705
        case blr_multiply:
 
2706
        case blr_divide:
 
2707
        case blr_concatenate:
 
2708
 
 
2709
        case blr_assignment:
 
2710
                *arg++ = parse(tdbb, csb, sub_type);
 
2711
                /* Fall into ... */
 
2712
 
 
2713
        case blr_handler:
 
2714
        case blr_loop:
 
2715
 
 
2716
        case blr_lock_state:
 
2717
        case blr_upcase:
 
2718
        case blr_lowcase:
 
2719
        case blr_negate:
 
2720
        case blr_not:
 
2721
        case blr_missing:
 
2722
        case blr_agg_count2:
 
2723
        case blr_agg_max:
 
2724
        case blr_agg_min:
 
2725
        case blr_agg_total:
 
2726
        case blr_agg_average:
 
2727
        case blr_agg_count_distinct:
 
2728
        case blr_agg_total_distinct:
 
2729
        case blr_agg_average_distinct:
 
2730
        case blr_post:
 
2731
        case blr_internal_info:
 
2732
                *arg++ = parse(tdbb, csb, sub_type);
 
2733
                break;
 
2734
 
 
2735
        case blr_agg_list:
 
2736
        case blr_agg_list_distinct:
 
2737
                *arg++ = parse(tdbb, csb, sub_type);
 
2738
                *arg++ = parse(tdbb, csb, VALUE);
 
2739
                break;
 
2740
 
 
2741
        case blr_exec_sql:
 
2742
                *arg++ = parse(tdbb, csb, sub_type);
 
2743
                break;
 
2744
 
 
2745
        case blr_exec_into:
 
2746
                n = BLR_WORD + 2; // e_exec_into_count - 1
 
2747
                node = PAR_make_node(tdbb, n);
 
2748
                arg = node->nod_arg;
 
2749
                *arg++ = parse(tdbb, csb, VALUE);
 
2750
                if (BLR_BYTE) // singleton
 
2751
                        *arg++ = 0;
 
2752
                else
 
2753
                        *arg++ = parse(tdbb, csb, STATEMENT);
 
2754
                for (n = 2/*e_exec_into_list*/; n < node->nod_count; n++)
 
2755
                        *arg++ = parse(tdbb, csb, VALUE);
 
2756
                break;
 
2757
 
 
2758
        case blr_post_arg:
 
2759
                *arg++ = parse(tdbb, csb, sub_type);
 
2760
                *arg++ = parse(tdbb, csb, sub_type);
 
2761
                break;
 
2762
 
 
2763
        case blr_null:
 
2764
        case blr_agg_count:
 
2765
        case blr_user_name:
 
2766
    case blr_current_role:
 
2767
        case blr_current_date:
 
2768
        case blr_start_savepoint:
 
2769
        case blr_end_savepoint:
 
2770
                break;
 
2771
 
 
2772
        case blr_current_time:
 
2773
                node->nod_arg[0] = (jrd_nod*) (IPTR) DEFAULT_TIME_PRECISION;
 
2774
                break;
 
2775
 
 
2776
        case blr_current_timestamp:
 
2777
                node->nod_arg[0] = (jrd_nod*) (IPTR) DEFAULT_TIMESTAMP_PRECISION;
 
2778
                break;
 
2779
 
 
2780
        case blr_current_time2:
 
2781
        case blr_current_timestamp2:
 
2782
                n = BLR_BYTE;
 
2783
                if (n > MAX_TIME_PRECISION) {
 
2784
                        ERR_post(isc_invalid_time_precision,
 
2785
                                         isc_arg_number, MAX_TIME_PRECISION, 0);
 
2786
                }
 
2787
                node->nod_arg[0] = (jrd_nod*) (IPTR) n;
 
2788
                break;
 
2789
 
 
2790
        case blr_user_savepoint:
 
2791
                {
 
2792
                        *arg++ = (jrd_nod*) (IPTR) BLR_BYTE;
 
2793
                        Firebird::MetaName name;
 
2794
                        par_name(csb, name);
 
2795
                        *arg++ = (jrd_nod*) stringDup(*tdbb->getDefaultPool(), name.c_str());
 
2796
                        break;
 
2797
                }
 
2798
 
 
2799
        case blr_store:
 
2800
        case blr_store2:
 
2801
                node->nod_arg[e_sto_relation] = parse(tdbb, csb, RELATION);
 
2802
                node->nod_arg[e_sto_statement] = parse(tdbb, csb, sub_type);
 
2803
                if (blr_operator == blr_store2)
 
2804
                        node->nod_arg[e_sto_statement2] = parse(tdbb, csb, sub_type);
 
2805
                break;
 
2806
 
 
2807
                /* Comparison operators */
 
2808
 
 
2809
        case blr_between:
 
2810
                *arg++ = parse(tdbb, csb, sub_type);
 
2811
 
 
2812
        case blr_equiv:
 
2813
        case blr_eql:
 
2814
        case blr_neq:
 
2815
        case blr_geq:
 
2816
        case blr_gtr:
 
2817
        case blr_leq:
 
2818
        case blr_lss:
 
2819
                *arg++ = parse(tdbb, csb, sub_type);
 
2820
                *arg++ = parse(tdbb, csb, sub_type);
 
2821
                node->nod_flags = nod_comparison;
 
2822
                break;
 
2823
 
 
2824
        case blr_erase:
 
2825
                n = BLR_BYTE;
 
2826
                if (n >= csb->csb_rpt.getCount() || !(csb->csb_rpt[n].csb_flags & csb_used))
 
2827
                        error(csb, isc_ctxnotdef, 0);
 
2828
                node->nod_arg[e_erase_stream] =
 
2829
                        (jrd_nod*) (IPTR) csb->csb_rpt[n].csb_stream;
 
2830
                break;
 
2831
        
 
2832
        case blr_modify:
 
2833
        case blr_modify2:
 
2834
                node = par_modify(tdbb, csb, blr_operator);
 
2835
                break;
 
2836
 
 
2837
        case blr_exec_proc:
 
2838
        case blr_exec_pid:
 
2839
                node = par_exec_proc(tdbb, csb, blr_operator);
 
2840
                break;
 
2841
 
 
2842
        case blr_pid:
 
2843
        case blr_procedure:
 
2844
                node = par_procedure(tdbb, csb, blr_operator);
 
2845
                break;
 
2846
 
 
2847
        case blr_function:
 
2848
                node = par_function(tdbb, csb);
 
2849
                break;
 
2850
 
 
2851
        case blr_index:
 
2852
                node->nod_arg[0] = parse(tdbb, csb, sub_type);
 
2853
                node->nod_arg[1] = par_args(tdbb, csb, sub_type);
 
2854
                break;
 
2855
 
 
2856
        case blr_for:
 
2857
                if (BLR_PEEK == (UCHAR) blr_stall)
 
2858
                        node->nod_arg[e_for_stall] = parse(tdbb, csb, STATEMENT);
 
2859
 
 
2860
                if (BLR_PEEK == (UCHAR) blr_rse ||
 
2861
                        BLR_PEEK == (UCHAR) blr_singular)
 
2862
                                node->nod_arg[e_for_re] = parse(tdbb, csb, TYPE_RSE);
 
2863
                else
 
2864
                        node->nod_arg[e_for_re] = par_rse(tdbb, csb, blr_operator);
 
2865
                node->nod_arg[e_for_statement] = parse(tdbb, csb, sub_type);
 
2866
                break;
 
2867
 
 
2868
        case blr_dcl_cursor:
 
2869
                {
 
2870
                        node->nod_arg[e_dcl_cursor_number] = (jrd_nod*) (IPTR) BLR_WORD;
 
2871
                        node->nod_arg[e_dcl_cursor_rse] = parse(tdbb, csb, TYPE_RSE);
 
2872
                        n = BLR_WORD;
 
2873
                        jrd_nod* temp = PAR_make_node(tdbb, n);
 
2874
                        temp->nod_type = nod_list;
 
2875
                        for (jrd_nod** ptr = temp->nod_arg; n; n--) {
 
2876
                                *ptr++ = parse(tdbb, csb, VALUE);
 
2877
                        }
 
2878
                        node->nod_arg[e_dcl_cursor_refs] = temp;
 
2879
                }
 
2880
                break;
 
2881
 
 
2882
        case blr_cursor_stmt:
 
2883
                n = BLR_BYTE;
 
2884
                node->nod_arg[e_cursor_stmt_op] = (jrd_nod*) (IPTR) n;
 
2885
                node->nod_arg[e_cursor_stmt_number] = (jrd_nod*) (IPTR) BLR_WORD;
 
2886
                switch (n) {
 
2887
                case blr_cursor_open:
 
2888
                case blr_cursor_close:
 
2889
                        break;
 
2890
                case blr_cursor_fetch:
 
2891
#ifdef SCROLLABLE_CURSORS
 
2892
                        if (BLR_PEEK == blr_seek)
 
2893
                                node->nod_arg[e_cursor_stmt_seek] = parse(tdbb, csb, STATEMENT);
 
2894
#endif
 
2895
                        csb->csb_g_flags |= csb_reuse_context;
 
2896
                        node->nod_arg[e_cursor_stmt_into] = parse(tdbb, csb, STATEMENT);
 
2897
                        csb->csb_g_flags &= ~csb_reuse_context;
 
2898
                        break;
 
2899
                default:
 
2900
                        syntax_error(csb, "cursor operation clause");
 
2901
                }
 
2902
                break;
 
2903
 
 
2904
        case blr_rse:
 
2905
        case blr_rs_stream:
 
2906
                node = par_rse(tdbb, csb, blr_operator);
 
2907
                break;
 
2908
 
 
2909
        case blr_singular:
 
2910
                node = parse(tdbb, csb, TYPE_RSE);
 
2911
                ((RecordSelExpr*) node)->nod_flags |= rse_singular;
 
2912
                break;
 
2913
 
 
2914
        case blr_relation:
 
2915
        case blr_rid:
 
2916
        case blr_relation2:
 
2917
        case blr_rid2:
 
2918
                node = par_relation(tdbb, csb, blr_operator, true);
 
2919
                break;
 
2920
 
 
2921
        case blr_union:
 
2922
                node = par_union(tdbb, csb, false);
 
2923
                break;
 
2924
 
 
2925
        case blr_recurse:
 
2926
                node = par_union(tdbb, csb, true);
 
2927
                break;
 
2928
 
 
2929
        case blr_aggregate:
 
2930
                node->nod_arg[e_agg_stream] = (jrd_nod*) (IPTR) par_context(csb, 0);
 
2931
                fb_assert((int) (IPTR)node->nod_arg[e_agg_stream] <= MAX_STREAMS);
 
2932
                node->nod_arg[e_agg_rse] = parse(tdbb, csb, TYPE_RSE);
 
2933
                node->nod_arg[e_agg_group] = parse(tdbb, csb, OTHER);
 
2934
                node->nod_arg[e_agg_map] =
 
2935
                        par_map(tdbb, csb, (USHORT)(IPTR) node->nod_arg[e_agg_stream]);
 
2936
                break;
 
2937
 
 
2938
        case blr_group_by:
 
2939
                node = par_sort(tdbb, csb, false);
 
2940
                return (node->nod_count) ? node : NULL;
 
2941
 
 
2942
        case blr_field:
 
2943
        case blr_fid:
 
2944
                node = par_field(tdbb, csb, blr_operator);
 
2945
                if (node->nod_type == nod_domain_validation || node->nod_type == nod_null)
 
2946
                        set_type = false;       // to not change nod->nod_type to nod_field
 
2947
                break;
 
2948
 
 
2949
        case blr_gen_id:
 
2950
        case blr_set_generator:
 
2951
                {
 
2952
                        Firebird::MetaName name;
 
2953
 
 
2954
                        par_name(csb, name);
 
2955
                        const SLONG tmp = MET_lookup_generator(tdbb, name.c_str());
 
2956
                        if (tmp < 0) {
 
2957
                                error(csb, isc_gennotdef,
 
2958
                                          isc_arg_string, ERR_cstring(name), 0);
 
2959
                        }
 
2960
                        node->nod_arg[e_gen_relation] = (jrd_nod*) (IPTR) tmp;
 
2961
                        node->nod_arg[e_gen_value] = parse(tdbb, csb, VALUE);
 
2962
 
 
2963
            /* CVC: There're thousand ways to go wrong, but I don't see any value
 
2964
               in posting dependencies with set generator since it's DDL, so I will
 
2965
               track only gen_id() in both dialects. */
 
2966
            if ((blr_operator == blr_gen_id)
 
2967
                && (csb->csb_g_flags & csb_get_dependencies))
 
2968
                        {
 
2969
                jrd_nod* dep_node = PAR_make_node (tdbb, e_dep_length);
 
2970
                dep_node->nod_type = nod_dependency;
 
2971
                dep_node->nod_arg [e_dep_object] = (jrd_nod*) (IPTR) tmp;
 
2972
                dep_node->nod_arg [e_dep_object_type] = (jrd_nod*)(IPTR) obj_generator;
 
2973
                csb->csb_dependencies.push(dep_node);
 
2974
            }
 
2975
 
 
2976
                }
 
2977
                break;
 
2978
 
 
2979
        case blr_record_version:
 
2980
        case blr_dbkey:
 
2981
                n = BLR_BYTE;
 
2982
                if (n >= csb->csb_rpt.getCount() || !(csb->csb_rpt[n].csb_flags & csb_used))
 
2983
                        error(csb, isc_ctxnotdef, 0);
 
2984
                node->nod_arg[0] = (jrd_nod*) (IPTR) csb->csb_rpt[n].csb_stream;
 
2985
                break;
 
2986
 
 
2987
        case blr_fetch:
 
2988
                par_fetch(tdbb, csb, node);
 
2989
                break;
 
2990
 
 
2991
        case blr_send:
 
2992
        case blr_receive:
 
2993
                n = BLR_BYTE;
 
2994
                node->nod_arg[e_send_message] = csb->csb_rpt[n].csb_message;
 
2995
                node->nod_arg[e_send_statement] = parse(tdbb, csb, sub_type);
 
2996
                break;
 
2997
 
 
2998
        case blr_message:
 
2999
                node = par_message(tdbb, csb);
 
3000
                break;
 
3001
 
 
3002
        case blr_literal:
 
3003
                node = par_literal(tdbb, csb);
 
3004
                break;
 
3005
 
 
3006
        case blr_cast:
 
3007
                node = par_cast(tdbb, csb);
 
3008
                break;
 
3009
 
 
3010
        case blr_extract:
 
3011
            // This forced conversion looks strange, but extract_part fits in a byte
 
3012
                node->nod_arg[e_extract_part] = (jrd_nod*)(U_IPTR) BLR_BYTE;
 
3013
                node->nod_arg[e_extract_value] = parse(tdbb, csb, sub_type);
 
3014
                node->nod_count = e_extract_count;
 
3015
                break;
 
3016
 
 
3017
        case blr_strlen:
 
3018
            // This forced conversion looks strange, but length_type fits in a byte
 
3019
                node->nod_arg[e_strlen_type] = (jrd_nod*)(U_IPTR) BLR_BYTE;
 
3020
                node->nod_arg[e_strlen_value] = parse(tdbb, csb, sub_type);
 
3021
                node->nod_count = e_strlen_count;
 
3022
                break;
 
3023
 
 
3024
        case blr_dcl_variable:
 
3025
                {
 
3026
                        dsc* desc = (dsc*) (node->nod_arg + e_dcl_desc);
 
3027
 
 
3028
                        ItemInfo itemInfo;
 
3029
 
 
3030
                        n = BLR_WORD;
 
3031
                        node->nod_arg[e_dcl_id] = (jrd_nod*) (IPTR) n;
 
3032
                        PAR_desc(tdbb, csb, desc, &itemInfo);
 
3033
                        vec<jrd_nod*>* vector = csb->csb_variables =
 
3034
                                vec<jrd_nod*>::newVector(*tdbb->getDefaultPool(), csb->csb_variables, n + 1);
 
3035
                        (*vector)[n] = node;
 
3036
 
 
3037
                        if (itemInfo.isSpecial())
 
3038
                        {
 
3039
                                csb->csb_dbg_info.varIndexToName.get(n, itemInfo.name);
 
3040
                                csb->csb_map_item_info.put(Item(nod_variable, n), itemInfo);
 
3041
                        }
 
3042
 
 
3043
                        if (itemInfo.explicitCollation)
 
3044
                        {
 
3045
                                jrd_nod* dep_node = PAR_make_node (tdbb, e_dep_length);
 
3046
                                dep_node->nod_type = nod_dependency;
 
3047
                                dep_node->nod_arg [e_dep_object] = (jrd_nod*)(IPTR) INTL_TEXT_TYPE(*desc);
 
3048
                                dep_node->nod_arg [e_dep_object_type] = (jrd_nod*)(IPTR) obj_collation;
 
3049
                                csb->csb_dependencies.push(dep_node);
 
3050
                        }
 
3051
                }
 
3052
                break;
 
3053
 
 
3054
        case blr_variable:
 
3055
                {
 
3056
                        n = BLR_WORD;
 
3057
                        node->nod_arg[e_var_id] = (jrd_nod*) (IPTR) n;
 
3058
                        vec<jrd_nod*>* vector = csb->csb_variables;
 
3059
                        if (!vector || n >= vector->count() ||
 
3060
                                !(node->nod_arg[e_var_variable] = (*vector)[n]))
 
3061
                        {
 
3062
                                syntax_error(csb, "variable identifier");
 
3063
                        }
 
3064
                }
 
3065
                break;
 
3066
 
 
3067
        case blr_parameter:
 
3068
        case blr_parameter2:
 
3069
        case blr_parameter3:
 
3070
                {
 
3071
                        jrd_nod* message;
 
3072
                        n = (USHORT) BLR_BYTE;
 
3073
                        if (n >= csb->csb_rpt.getCount() ||
 
3074
                                !(message = csb->csb_rpt[n].csb_message))
 
3075
                        {
 
3076
                                error(csb, isc_badmsgnum, 0);
 
3077
                        }
 
3078
                        node->nod_arg[e_arg_message] = message;
 
3079
                        n = BLR_WORD;
 
3080
                        node->nod_arg[e_arg_number] = (jrd_nod*) (IPTR) n;
 
3081
                        const Format* format = (Format*) message->nod_arg[e_msg_format];
 
3082
                        if (n >= format->fmt_count)
 
3083
                                error(csb, isc_badparnum, 0);
 
3084
                        if (blr_operator != blr_parameter) {
 
3085
                                jrd_nod* temp = PAR_make_node(tdbb, e_arg_length);
 
3086
                                node->nod_arg[e_arg_flag] = temp;
 
3087
                                node->nod_count = 1;
 
3088
                                temp->nod_count = 0;
 
3089
                                temp->nod_type = nod_argument;
 
3090
                                temp->nod_arg[e_arg_message] = message;
 
3091
                                n = BLR_WORD;
 
3092
                                temp->nod_arg[e_arg_number] = (jrd_nod*) (IPTR) n;
 
3093
                                if (n >= format->fmt_count)
 
3094
                                        error(csb, isc_badparnum, 0);
 
3095
                        }
 
3096
                        if (blr_operator == blr_parameter3) {
 
3097
                                jrd_nod* temp = PAR_make_node(tdbb, e_arg_length);
 
3098
                                node->nod_arg[e_arg_indicator] = temp;
 
3099
                                node->nod_count = 2;
 
3100
                                temp->nod_count = 0;
 
3101
                                temp->nod_type = nod_argument;
 
3102
                                temp->nod_arg[e_arg_message] = message;
 
3103
                                n = BLR_WORD;
 
3104
                                temp->nod_arg[e_arg_number] = (jrd_nod*) (IPTR) n;
 
3105
                                if (n >= format->fmt_count)
 
3106
                                        error(csb, isc_badparnum, 0);
 
3107
                        }
 
3108
                }
 
3109
                break;
 
3110
 
 
3111
        case blr_stall:
 
3112
                break;
 
3113
 
 
3114
        case blr_select:
 
3115
        case blr_begin:
 
3116
                {
 
3117
                        NodeStack stack;
 
3118
 
 
3119
                        while (BLR_PEEK != (UCHAR) blr_end) {
 
3120
                                if (blr_operator == blr_select && BLR_PEEK != blr_receive)
 
3121
                                        syntax_error(csb, "blr_receive");
 
3122
                                stack.push(parse(tdbb, csb, sub_type));
 
3123
                        }
 
3124
                        BLR_BYTE; // skip blr_end
 
3125
                        node = PAR_make_list(tdbb, stack);
 
3126
                }
 
3127
                break;
 
3128
 
 
3129
        case blr_block:
 
3130
                {
 
3131
                        NodeStack stack;
 
3132
 
 
3133
                        node->nod_arg[e_blk_action] = parse(tdbb, csb, sub_type);
 
3134
                        while (BLR_PEEK != (UCHAR) blr_end)
 
3135
                        {
 
3136
                                stack.push(parse(tdbb, csb, sub_type));
 
3137
                        }
 
3138
                        BLR_BYTE; // skip blr_end
 
3139
                        node->nod_arg[e_blk_handlers] = PAR_make_list(tdbb, stack);
 
3140
                }
 
3141
                break;
 
3142
 
 
3143
        case blr_error_handler:
 
3144
                node->nod_arg[e_err_conditions] = (jrd_nod*) par_conditions(tdbb, csb);
 
3145
                node->nod_arg[e_err_action] = parse(tdbb, csb, sub_type);
 
3146
                break;
 
3147
 
 
3148
        case blr_abort:
 
3149
                {
 
3150
                        const bool flag = (BLR_PEEK == blr_exception_msg);
 
3151
                        node->nod_arg[e_xcp_desc] = (jrd_nod*) par_condition(tdbb, csb);
 
3152
                        if (flag)
 
3153
                        {
 
3154
                                node->nod_arg[e_xcp_msg] = parse(tdbb, csb, sub_type);
 
3155
                        }
 
3156
                        break;
 
3157
                }
 
3158
 
 
3159
        case blr_if:
 
3160
                node->nod_arg[e_if_boolean] = parse(tdbb, csb, TYPE_BOOL);
 
3161
                node->nod_arg[e_if_true] = parse(tdbb, csb, sub_type);
 
3162
                if (BLR_PEEK == (UCHAR) blr_end) {
 
3163
                        node->nod_count = 2;
 
3164
                        BLR_BYTE; // skip blr_end
 
3165
                        break;
 
3166
                }
 
3167
                node->nod_arg[e_if_false] = parse(tdbb, csb, sub_type);
 
3168
                break;
 
3169
 
 
3170
        case blr_label:
 
3171
                node->nod_arg[e_lbl_label] = (jrd_nod*) (IPTR) BLR_BYTE;
 
3172
                node->nod_arg[e_lbl_statement] = parse(tdbb, csb, sub_type);
 
3173
                break;
 
3174
 
 
3175
        case blr_leave:
 
3176
                node->nod_arg[0] = (jrd_nod*) (IPTR) BLR_BYTE;
 
3177
                break;
 
3178
 
 
3179
 
 
3180
        case blr_maximum:
 
3181
        case blr_minimum:
 
3182
        case blr_count:
 
3183
/* count2
 
3184
    case blr_count2:
 
3185
*/
 
3186
        case blr_average:
 
3187
        case blr_total:
 
3188
        case blr_from:
 
3189
        case blr_via:
 
3190
                node->nod_arg[e_stat_rse] = parse(tdbb, csb, TYPE_RSE);
 
3191
                if (blr_operator != blr_count)
 
3192
                        node->nod_arg[e_stat_value] = parse(tdbb, csb, VALUE);
 
3193
                if (blr_operator == blr_via)
 
3194
                        node->nod_arg[e_stat_default] = parse(tdbb, csb, VALUE);
 
3195
                break;
 
3196
 
 
3197
#ifdef SCROLLABLE_CURSORS
 
3198
        case blr_seek:
 
3199
                node->nod_arg[e_seek_direction] = parse(tdbb, csb, VALUE);
 
3200
                node->nod_arg[e_seek_offset] = parse(tdbb, csb, VALUE);
 
3201
                break;
 
3202
#endif
 
3203
 
 
3204
        case blr_init_variable:
 
3205
                {
 
3206
                        n = BLR_WORD;
 
3207
                        node->nod_arg[e_init_var_id] = (jrd_nod*)(U_IPTR) n;
 
3208
                        vec<jrd_nod*>* vector = csb->csb_variables;
 
3209
                        if (!vector || n >= vector->count() ||
 
3210
                                !(node->nod_arg[e_init_var_variable] = (*vector)[n]))
 
3211
                        {
 
3212
                                syntax_error(csb, "variable identifier");
 
3213
                        }
 
3214
                }
 
3215
                break;
 
3216
 
 
3217
        case blr_sys_function:
 
3218
                node = par_sys_function(tdbb, csb);
 
3219
                break;
 
3220
 
 
3221
        default:
 
3222
                syntax_error(csb, elements[expected]);
 
3223
        }
 
3224
 
 
3225
        if (set_type)
 
3226
        {
 
3227
                if (csb->csb_g_flags & csb_blr_version4)
 
3228
                        node->nod_type = (NOD_T) (USHORT) blr_table4[(int) blr_operator];
 
3229
                else
 
3230
                        node->nod_type = (NOD_T) (USHORT) blr_table[(int) blr_operator];
 
3231
        }
 
3232
 
 
3233
        size_t pos = 0;
 
3234
        if (csb->csb_dbg_info.blrToSrc.find(blr_offset, pos))
 
3235
        {
 
3236
                Firebird::MapBlrToSrcItem& i = csb->csb_dbg_info.blrToSrc[pos];
 
3237
                jrd_nod* node_src = PAR_make_node(tdbb, e_src_info_length);
 
3238
 
 
3239
                node_src->nod_type = nod_src_info;
 
3240
                node_src->nod_arg[e_src_info_line] = (jrd_nod*) (IPTR) i.mbs_src_line;
 
3241
                node_src->nod_arg[e_src_info_col] = (jrd_nod*) (IPTR) i.mbs_src_col;
 
3242
                node_src->nod_arg[e_src_info_node] = node;
 
3243
 
 
3244
                return node_src;
 
3245
        }
 
3246
 
 
3247
        return node;
 
3248
}
 
3249
 
 
3250
 
 
3251
static void syntax_error(CompilerScratch* csb, const TEXT* string)
 
3252
{
 
3253
/**************************************
 
3254
 *
 
3255
 *      s y n t a x _ e r r o r
 
3256
 *
 
3257
 **************************************
 
3258
 *
 
3259
 * Functional description
 
3260
 *      Post a syntax error message.
 
3261
 *
 
3262
 **************************************/
 
3263
 
 
3264
        error(csb, isc_syntaxerr,
 
3265
                  isc_arg_string, string,
 
3266
                  isc_arg_number, (SLONG) (csb->csb_running - csb->csb_blr - 1),
 
3267
                  isc_arg_number, (SLONG) csb->csb_running[-1], 0);
 
3268
}
 
3269
 
 
3270
 
 
3271
static void warning(CompilerScratch* csb, ...)
 
3272
{
 
3273
/**************************************
 
3274
 *
 
3275
 *      w a r n i n g
 
3276
 *
 
3277
 **************************************
 
3278
 *
 
3279
 * Functional description
 
3280
 *      This is for GBAK so that we can pass warning messages
 
3281
 *      back to the client.  DO NOT USE this function until we
 
3282
 *      fully implement warning at the engine level.
 
3283
 *
 
3284
 *      We will use the status vector like a warning vector.  What
 
3285
 *      we are going to do is leave the [1] position of the vector 
 
3286
 *      as 0 so that this will not be treated as an error, and we
 
3287
 *      will place our warning message in the consecutive positions.
 
3288
 *      It will be up to the caller to check these positions for
 
3289
 *      the message.
 
3290
 *
 
3291
 **************************************/
 
3292
        ISC_STATUS *p;
 
3293
        int type;
 
3294
        va_list args;
 
3295
 
 
3296
        thread_db* tdbb = JRD_get_thread_data();
 
3297
 
 
3298
        va_start(args, csb);
 
3299
 
 
3300
        p = tdbb->tdbb_status_vector;
 
3301
 
 
3302
/* Make sure that the [1] position is 0
 
3303
   indicating that no error has occured */
 
3304
 
 
3305
        *p++ = isc_arg_gds;
 
3306
        *p++ = 0;
 
3307
 
 
3308
/* Now place your warning messages starting
 
3309
   with position [2] */
 
3310
 
 
3311
        *p++ = isc_arg_gds;
 
3312
        *p++ = va_arg(args, ISC_STATUS);
 
3313
 
 
3314
/* Pick up remaining args */
 
3315
 
 
3316
        while ( (*p++ = type = va_arg(args, int)) )
 
3317
        {
 
3318
                switch (type) {
 
3319
                case isc_arg_gds:
 
3320
                        *p++ = (ISC_STATUS) va_arg(args, ISC_STATUS);
 
3321
                        break;
 
3322
 
 
3323
                case isc_arg_string:
 
3324
                case isc_arg_interpreted:
 
3325
                        *p++ = (ISC_STATUS) va_arg(args, TEXT *);
 
3326
                        break;
 
3327
 
 
3328
                case isc_arg_cstring:
 
3329
                        *p++ = (ISC_STATUS) va_arg(args, int);
 
3330
                        *p++ = (ISC_STATUS) va_arg(args, TEXT *);
 
3331
                        break;
 
3332
 
 
3333
                case isc_arg_number:
 
3334
                        *p++ = (ISC_STATUS) va_arg(args, SLONG);
 
3335
                        break;
 
3336
 
 
3337
                default:
 
3338
                        fb_assert(FALSE);
 
3339
                case isc_arg_vms:
 
3340
                case isc_arg_unix:
 
3341
                case isc_arg_win32:
 
3342
                        *p++ = va_arg(args, int);   
 
3343
                        break; 
 
3344
                }
 
3345
        }
 
3346
        va_end(args);
 
3347
}
 
3348