diff --git a/doc/sql.extensions/README.context_variables b/doc/sql.extensions/README.context_variables new file mode 100644 index 0000000000..40f7fa254f --- /dev/null +++ b/doc/sql.extensions/README.context_variables @@ -0,0 +1,132 @@ +------------------------ +System context variables +------------------------ + + +CURRENT_CONNECTION / CURRENT_TRANSACTION (FB 1.5) +------------------------------------------------- + + Function: + Returns system identifier of the active connection/transaction, + i.e. a connection/transaction, in which context the given SQL + statement is executed. + + Author: + Dmitry Yemanov + + Syntax rules: + CURRENT_CONNECTION / CURRENT_TRANSACTION + + Type: + INTEGER + + Scope: + DSQL, PSQL + + Example(s): + 1. SELECT CURRENT_CONNECTION FROM RDB$DATABASE; + 2. NEW.CONN_ID = CURRENT_TRANSACTION; + 3. EXECUTE PROCEDURE P_LOGIN(CURRENT_CONNECTION); + + +ROW_COUNT (FB 1.5) +------------------ + + Function: + Returns number of rows, affected by the last SQL statement. + + Author: + Dmitry Yemanov + + Syntax rules: + ROW_COUNT + + Type: + INTEGER + + Scope: + PSQL, context of the given procedure/trigger. + + Example(s): + UPDATE TABLE1 SET FIELD1 = 0 WHERE ID = :ID; + IF (ROW_COUNT = 0) THEN + INSERT INTO TABLE1 (ID, FIELD1) VALUES (:ID, 0); + + Note(s): + After SELECT statements ROW_COUNT always contains zero, + i.e. it can be used for INSERT/UPDATE/DELETE statements only. + It may be a subject of change in the following versions. + + +SQLCODE / GDSCODE (FB 1.5) +-------------------------- + + Function: + Returns numeric error code for the active exception. + + Author: + Dmitry Yemanov + + Syntax rules: + SQLCODE / GDSCODE + + Type: + INTEGER + + Scope: + PSQL, context of the exception handling block. + + Example(s): + BEGIN + ... + WHEN SQLCODE -802 THEN + EXCEPTION E_EXCEPTION_1; + WHEN SQLCODE -803 THEN + EXCEPTION E_EXCEPTION_2; + WHEN ANY DO + EXECUTE PROCEDURE P_ANY_EXCEPTION(SQLCODE); + END + + Note(s): + 1. GDSCODE variable returns a numeric representation of the + appropriate Firebird error code. + 2. Both SQLCODE and GDSCODE always evaluate to zero outside + the exception handling block. + 3. If you catch exceptions with 'WHEN SQLCODE' block, then only + SQLCODE variable contains the error code inside this block, + whilst GDSCODE contains zero. Obviously, this situation is + opposite for 'WHEN GDSCODE' block. + 4. For 'WHEN ANY' block, the error code is set in SQLCODE + variable only. + 5. If user-defined exception is thrown, both SQLCODE and GDSCODE + variables contain zero, regardless of the exception handling + block type. + + See also: + README.exception_handling + + +INSERTING / UPDATING / DELETING (FB 1.5) +---------------------------------------- + + Function: + Determines type of row operation being executed. + + Author: + Dmitry Yemanov + + Syntax rules: + INSERTING / UPDATING / DELETING + + Type: + BOOLEAN (emulated via pseudo-expression in FB 1.5) + + Scope: + PSQL, triggers only. + + Example(s): + IF (INSERTING OR DELETING) THEN + NEW.ID = GEN_ID(G_GENERATOR_1, 1); + + See also: + README.universal_triggers diff --git a/doc/sql.extensions/README.data_types b/doc/sql.extensions/README.data_types new file mode 100644 index 0000000000..c6d846c7e4 --- /dev/null +++ b/doc/sql.extensions/README.data_types @@ -0,0 +1,34 @@ +--------------------- +Native SQL data types +--------------------- + + +BIGINT (FB 1.5) +-------------- + + Function: + SQL99-compliant exact numeric type. + + Author: + Dmitry Yemanov + + Syntax rules: + BIGINT + + Storage: + 64-bit, signed + + Example(s): + 1. DECLARE VARIABLE VAR1 BIGINT; + 2. CREATE TABLE TABLE1 (FIELD1 BIGINT); + + Note(s): + Quote from the SQL-99 specification: + + SMALLINT, INTEGER, and BIGINT specify the data type exact numeric, + with scale of 0 (zero) and binary or decimal precision. The choice + of binary versus decimal precision is implementation-defined, but + the same radix shall be chosen for all three data types. The precision + of SMALLINT shall be less than or equal to the precision of INTEGER, + and the precision of BIGINT shall be greater than or equal to the + precision of INTEGER. diff --git a/doc/sql.extensions/README.exception_handling b/doc/sql.extensions/README.exception_handling new file mode 100644 index 0000000000..7e61e39b08 --- /dev/null +++ b/doc/sql.extensions/README.exception_handling @@ -0,0 +1,77 @@ +------------------ +Exception handling +------------------ + +The common syntax rules for EXCEPTION statement is: + + EXCEPTION [[name] [value]]; + + +Run-time exception messages (FB 1.5) +------------------------------------ + + Function: + Allows to throw exceptions with text message + defined at runtime. + + Author: + Dmitry Yemanov + + Syntax rules: + EXCEPTION ; + + Scope: + PSQL + + Example(s): + 1. EXCEPTION E_EXCEPTION_1 'Error!'; + 2. EXCEPTION E_EXCEPTION_2 'Wrong type for record with ID=' || new.ID; + + +Exception re-raise semantics (FB 1.5) +------------------------------------- + + Function: + Allows to re-initiate catched exception. + + Author: + Digitman + + Syntax rules: + EXCEPTION; + + Scope: + PSQL, context of the exception handling block + + Example(s): + BEGIN + ... + WHEN SQLCODE -802 THEN + EXCEPTION E_ARITH_EXCEPT; + WHEN SQLCODE -802 THEN + EXCEPTION E_KEY_VIOLATION; + WHEN ANY THEN + EXCEPTION; + END + + Note(s): + Evaluates to no-op if used outside the exception handling block. + + +Run-time error codes (FB 1.5) +----------------------------- + + Function: + Allows to get a numeric error code for the catched exception. + + Author: + Dmitry Yemanov + + Syntax rules: + SQLCODE / GDSCODE; + + Scope: + PSQL, context of the exception handling block + + See also: + README.context_variables diff --git a/doc/sql.extensions/README.universal_triggers b/doc/sql.extensions/README.universal_triggers new file mode 100644 index 0000000000..f0c77193cd --- /dev/null +++ b/doc/sql.extensions/README.universal_triggers @@ -0,0 +1,78 @@ +--------------------------- +Universal triggers (FB 1.5) +--------------------------- + + Function: + Allows triggers that handle multiple row operations. + + Author: + Dmitry Yemanov + + Syntax rules: + CREATE TRIGGER name FOR table + [ACTIVE | INACTIVE] + {BEFORE | AFTER} + [POSITION number] + AS trigger_body + + ::= [OR [OR ]] + ::= {INSERT | UPDATE | DELETE} + + Example(s): + 1. CREATE TRIGGER TRIGGER1 FOR TABLE1 BEFORE INSERT OR UPDATE AS ...; + 2. CREATE TRIGGER TRIGGER2 FOR TABLE2 AFTER INSERT OR UPDATE OR DELETE AS ...; + + ODS: + Encoding of field RDB$TRIGGER_TYPE (relation RDB$TRIGGERS) has been extended + to allow complex trigger actions. Coding scheme is shown below (in C syntax): + + // trigger type prefixes + #define TRIGGER_BEFORE 0 + #define TRIGGER_AFTER 1 + + // trigger type suffixes + #define TRIGGER_INSERT 1 + #define TRIGGER_UPDATE 2 + #define TRIGGER_DELETE 3 + + // that's how trigger action types are encoded + /* + bit 0 = TRIGGER_BEFORE/TRIGGER_AFTER flag, + bits 1-2 = TRIGGER_INSERT/TRIGGER_UPDATE/TRIGGER_DELETE (slot #1), + bits 3-4 = TRIGGER_INSERT/TRIGGER_UPDATE/TRIGGER_DELETE (slot #2), + bits 5-6 = TRIGGER_INSERT/TRIGGER_UPDATE/TRIGGER_DELETE (slot #3), + and finally the above calculated value is decremented + + example #1: + TRIGGER_AFTER_DELETE = + = ((TRIGGER_DELETE << 1) | TRIGGER_AFTER) - 1 = + = ((3 << 1) | 1) - 1 = + = 0x00000110 (6) + + example #2: + TRIGGER_BEFORE_INSERT_UPDATE = + = ((TRIGGER_UPDATE << 3) | (TRIGGER_INSERT << 1) | TRIGGER_BEFORE) - 1 = + = ((2 << 3) | (1 << 1) | 0) - 1 = + = 0x00010001 (17) + + example #3: + TRIGGER_AFTER_UPDATE_DELETE_INSERT = + = ((TRIGGER_INSERT << 5) | (TRIGGER_DELETE << 3) | (TRIGGER_UPDATE << 1) | TRIGGER_AFTER) - 1 = + = ((1 << 5) | (3 << 3) | (2 << 1) | 1) - 1 = + = 0x00111100 (60) + */ + + Note(s): + 1. One-action triggers are fully compatible at ODS level with FB 1.0. + 2. RDB$TRIGGER_TYPE encoding is order-dependant, i.e. + BEFORE INSERT OR UPDATE and BEFORE UPDATE OR INSERT will be coded differently, + although they have the same semantics and will be executed exactly the same way. + 3. In multiple-action triggers both OLD and NEW contexts are available. If the + trigger invocation forbids one of them (e.g. OLD context for INSERT operation), + then all fields of that context will eveluate to NULL. If you assign to + unproper context, runtime exception will be thrown. + 4. You may use new context variables INSERTING/UPDATEING/DELETING to check the + operation type at runtime. + + See also: + README.context_variables