Archive for May, 2009

technicolor terminal : the Cygwin saga

Not too long ago I posted a snippet that explained how to enable the 256-color display capabilities of terminals that support it. I’ve since had a bit of trouble getting this to work in terminals under Cygwin. Applications like Vim understand the capabilities of such a terminal, but less and man would complain:

   WARNING: terminal is not fully functional

After bit of digging I finally realised that it isn’t enough to have entries for those terminal types in /usr/share/terminfo/*/*. Some apps expect to find the terminal capabilties described in a termcap file, either /etc/termcap or ~/.termcap. Fortunately, there is an easy way to export the capabilities described in the terminfo database entries to a termcap file:

   $ infocmp -C xterm-256color >> ~/.termcap

If you’re a screen user, its worth exporting the entry for screen-256color too. man infocmp for more information.

show me the matches

Something that I’ve never been particularly fond of is the way that Vim does filename completion. Completing with the first available match and then allowing one to cycle through the remaining matches with <TAB> feels less effecient than presenting only the longest matching portion of the filename, allowing one to further refine the partially-completed string or retrieve all candidates using <TAB><TAB>. The latter is, of course, the model used by bash and Emacs.

As it turns out Vim has options that control this behaviour:

   set wildmode=longest:full
   set wildmenu

This wildmode setting instructs Vim to complete only the longest common portion of the filename and, if wildmenu is enabled, display the candidates in a status menu. This wildmenu setting, of course, turns this feature on.

unlocking bash

I periodically manage to lock bash with an errant C-S (that’s <ctrl>+<s> in Emacs-speak). The only way to recover seemed to be kill the shell window (if I was fortunate enough to be in a windowing environment, or in screen).

Hannu Nevalainen posted a solution to this problem to the Cygwin mailing list. The problem relates to the use of C-S and C-Q as the ASCII XOFF and XON flow control characters respectively. Having hit C-S, simply hit C-Q to store the bash session.

It seems that my education is lacking some terminal history!

declaring db2 global temporary tables & cursors

Since v7.1 DB2 LUW (or UDB, if you prefer) has supported session-specific global temporary tables. Once declared, the table may be referenced until the session ends, at which point the rows are deleted and the description is dropped. (See the IBM Infocenter pages for details). The syntax for declaring these tables is, however, a little arcane, and I found using them in conjuction with cursor declarations somewhat tricky.

Specifically, if the cursor is opened over the temporary table, the cursor declaration must follow the table declaration. However, it seems that DB2’s parser expects only variable declarations to follow the table declaration. For example, the following code:

   connect to testdb@
   set current schema='testschema'@
   
   DROP PROCEDURE temp_proc@
   CREATE PROCEDURE temp_proc(
         IN input_var CHAR(1))
      LANGUAGE SQL
      DYNAMIC RESULT SETS 1
      CALLED ON NULL INPUT
   BEGIN
   
      DECLARE SQLCODE INTEGER DEFAULT 0;
      DECLARE GLOBAL TEMPORARY TABLE t_y_or_n (y_or_n char(1))
         ON COMMIT PRESERVE ROWS NOT LOGGED;
   
      DECLARE local_var CHAR(1);
      DECLARE crsr CURSOR WITH RETURN TO CLIENT FOR
         SELECT y_or_n FROM session.t_y_or_n WHERE y_or_n=local_var;
      INSERT INTO session.t_y_or_n
         SELECT ibmreqd FROM sysibm.sysdummy1;
      SET local_var = input_var;
   
      OPEN crsr;
   
   END@
   
   CALL temp_proc('Y')@
   terminate@

yields the error:

   DB21034E The command was processed as an SQL statement because it
   was not a valid Command Line Processor command. During SQL
   processing it returned:
   SQL0104N An unexpected token "<variable declaration>" was
   found following "". Expected tokens may include: "<SQL statement>".
   LINE NUMBER=12.
   SQLSTATE=42601

The solution seems to be to put the table declaration and the the cursor declaration in different scope. This is achieved using labels, i.e.:

   connect to testdb@
   set current schema='testschema'@
   
   DROP PROCEDURE temp_proc@
   CREATE PROCEDURE temp_proc(
         IN input_var CHAR(1))
      LANGUAGE SQL
      DYNAMIC RESULT SETS 1
      CALLED ON NULL INPUT
   P1 : BEGIN
      DECLARE SQLCODE INTEGER DEFAULT 0;
      DECLARE GLOBAL TEMPORARY TABLE t_y_or_n (y_or_n char(1))
         ON COMMIT PRESERVE ROWS NOT LOGGED;
      P2 : BEGIN
         DECLARE local_var CHAR(1);
         DECLARE crsr CURSOR WITH RETURN TO CLIENT FOR
            SELECT y_or_n FROM session.t_y_or_n WHERE y_or_n=local_var;
         INSERT INTO session.t_y_or_n
            SELECT ibmreqd FROM sysibm.sysdummy1;
         SET local_var = input_var;
         OPEN crsr;
      END P2;
   END P1@
   
   CALL temp_proc('Y')@
   terminate@

The above code can be run by copying it into a file and executing it with:

   db2 -td@ -v -f <script_name>

Thanks to nemali on the Dev Shed forums for his/her post on the subject.

retrieving large values without truncation in the DB2 CLP

The DB2 command-line processor (CLP; invoked from a shell with the command db2) truncates output greater than 8K. One way to retrieve the full text of a column value that exceeds that size (e.g. CLOB data) is to use the export command. For example, having connected a database and set the current schema, one could use a statement of the following form from within the db2 CLP (note that the "db2 =>" is the CLP prompt):

   db2 => export to result.del of del modified by chardel'' coldel; decpt, select <column> from <table>

The "of del" indicates that the output file should contain delimited data. The delimiters used, and how they are applied, is defined by the modified by clause and its qualifiers "chardel" and "coldel";

  • chardel: defines the character that will be used to delimit character data; in the above example a single quote (') is used.
  • coldel: defines the character that will be used to delimit columns; in the above example a semi-colon (;) is used.

The file produced by this statement would look something like:

   1;'foo';256;'KB'
   2;'bar';512;'KB'
   3;'baz';1;'MB'

Note, however, that if the column value that is being exported is longer than the default character column that can be exported, export will truncate the data and issue the warning:

SQL3132W The character data in column "DATA" will be truncated to size "32700"

To work around this, the lobfile parameter may be used to specify a base prefix for the files that will be used to store LOB data without truncation. The form of the command then becomes:

   export to result.del of del lobfile result_lob_ modified by chardel'' coldel; decpt, select data from debug_data

For more information please refer the IBM Infocenter pages that describe the EXPORT command, and its file-type modifiers.