Keyword Migration - Design Specification

Functional Specification: Keyword Migration

High Level Design

High Level Algorithm

Each time a client connects to an InterBase server, it connects based on a remote procotol version. This protocol version helps the server understand the feature set supported by the client as well as informing the server if any special processing is needed before sending a packet to the client. The remote protocol version does not explicitly define the version of the client, however, in this case it will be used as such.

When a client connects to the server with an operation of op_prepare_statement, op_execute_immediate, or op_execute_immediate2, the remote protocol version is checked to determine the version of the keywords to use. This parser version is then passed on through to either dsql8_prepare or dsql8_execute_immediate, depending on the operation requested.

Regardless of the operation, we will go through dsql.c::prepare and then through dsql_yyparse. dsql_yyparse is the entrypoint into the parser and the area where the parser version will be used.

In dsql_yyparse, yylex will be called each time the parser needs a new token to complete a production rule. Yylex, in turn, will read in the next token from the request and determine the token type. If the token turns out to be a string, a call is made to HSHD_lookup to determine if the string should be used as a symbol token or as a keyword token. If the string is found in the hash table, the version of the hash element is compared with the parser version. If the parser version is less than the version of the hash element, then the string was not a keyword at the time it was created and therefore must be returned as a symbol token. If the parser version is greater than or equal to the version of the keyword, then the string is returned as being a keyword token.

Detailed Design

Internal Data Structures

Keywords.h / Parse.y: Structure TOK

  • Added tok_version
  • Each keyword now has a version associated with it

Sym.h: Sructure SYM

  • Added sym_version

Detailed Algorithm

server.c

prepare_statement
     USHORT parser_version;
     parser_version = (port->port_protocol < PROTOCOL_VERSION10 : 1 ? 2);
     GDS_DSQL_PREPARE (
             (prepare->p_sqlst_SQL_dialect *10) + parser_version,
             ...
             );

execute_immediate
     USHORT parser_version;
     parser_version = (port->port_protocol < PROTOCOL_VERSION10 : 1 ? 2);
     GDS_DSQL_EXECUTE_IMMED (
             ...
             (exnow->p_sqlst_SQL_dialect *10) + parser_version,
             ...
             );

ipserver.c

prepare_statement
     USHORT parser_version;
     parser_version = 2;
     GDS_DSQL_PREPARE (
             ...
             (dialect *10) + parser_version,
             ...
             );

execute_immediate
     USHORT parser_version;
     parser_version = 2;
     GDS_DSQL_EXECUTE_IMMED (
             ...
             (dialect *10) + parser_version,
             ...
             );

hsh.c

HSHD_lookup
     ... lookup symbol in hash table ....
     if (symbol)
         {
         if (parser_version < symbol->sym_version && type == SYM_keyword)
             return NULL;
         }
     return SYMBOL;

parse.y

LEX_dsql_init
     add token version to hash table
     ...
     symbol->sym_version = token->tok_version;
     ...

Notes:

  • The calculation that combines the client dialect and parser version is needed in order to keep the external API to this functions consistent.
  • In HSHD_lookup, returning symbol==NULL is a valid. This means that the string was not found in the hash table. This can occur when looking for objects other than parser keywords. The check for parser version is only made for keywords so as not to interfere with any other use of the hash table. Because of this, all functions which use HSHD_lookup for other information can pass 0 for the parser version.
  • For NT installations of the product, an assumption is being made that the client and server are upgraded at the same time. This would mean that local access to the server will automatically change once the server is upgraded

New/Affected modules

New/Affected modules
Component File Function Change
remote server.c execute_immediate, prepare_statement Determine the parser version based on the remote protocol version
ipserver ipserver.c prepare_statement, execute_immediate Set the parser version to 2 as the client and server versions for LOCAL NT ACCESS should always be the same.
dsql parse_proto.h dsql_yyparse Updated function prototype
dsql parse.y yylex Updated prototype to HSHD_lookup to use parser_version based on remote protocol
dsql parse.y TOK structure added element tok_version to hold the version of the keyword
dsql keywords.h NA Added a version to each keyword. Keywords prior to 6.0 are version 1, 6.0 keywords are version 2
dsql sym.h SYM structure Added element sym_version to hold the version of the symbol in the hash table
dsql hsh_proto.h HSHD_lookup Updated function prototype
dsql hsh.c HSHD_lookup Once a string is found in the hash table, compare the version of the symbol to the parser version
dsql metd.e METD_drop_procedure, METD_drop_relation, METD_get_collation, METD_get_charset, METD_get_function, METD_get_procedure, METD_get_relation Updated prototype to HSHD_lookup to use parser_version of 0
dsql dsql.c DSQL_set_cursor_name Updated prototype to HSHD_lookup to use parser_version of 0
dsql dsql.c dsql8_prepare, dsql8_execute_immediate Extract parser version from client dialect
dsql pass1.c Multiple functions Updated prototype to HSHD_lookup to use parser_version of 0

Testing Considerations

In order to properly test this feature, there needs to be an InterBase V5.6 application that does uses some of the InterBase V6.0 keywords as the name of database objects. This should be run against InterBase V5.6. Then once it has been run against an InterBase V5.6 server, it should be run in its exact state against an InterBase V6.0 server. The application should work exactly the same regardless of the server version. Lastly, the client should be upgraded to InterBase V6.0. Now, the application should start failing with parser errors when attempting to use the InterBase V6.0 keywords as symbols.