text:
// Copyright (c) 2014 Whiteout Networks

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

(function(root, factory) {
    'use strict';

    if (typeof define === 'function' && define.amd && typeof nodeRequire === 'undefined') {
        // amd
        define(['tcp-socket-tls'], factory.bind(null, navigator));
    } else if (typeof define === 'function' && define.amd && typeof nodeRequire !== 'undefined') {
        // amd under node-webkit
        define([], factory.bind(null, navigator, null, nodeRequire('net'), nodeRequire('tls')));
    } else if (typeof exports === 'object' && typeof navigator !== 'undefined') {
        // common.js for browser apps with native socket support
        module.exports = factory(navigator, require('./tcp-socket-tls'));
    } else if (typeof exports === 'object') {
        // common.js for node.js
        module.exports = factory(null, null, require('net'), require('tls'));
    } else {
        // global browser import
        navigator.TCPSocket = factory(navigator, root.TLS);
    }
})(this, function(root, TLS, net, tls) {
    'use strict';

    // Constants used for tls-worker
    var EVENT_INBOUND = 'inbound',
        EVENT_OUTBOUND = 'outbound',
        EVENT_OPEN = 'open',
        EVENT_CLOSE = 'close',
        EVENT_ERROR = 'error',
        EVENT_CONFIG = 'configure',
        EVENT_CERT = 'cert',
        EVENT_HANDSHAKE = 'handshake';

    // the class to be implemented
    var TCPSocket = function() {
        throw new Error('Runtime does not offer TCPSockets!');
    };

    // detect runtime
    if (root && typeof io === 'undefined') {
        // check for native support
        root.TCPSocket = root.TCPSocket || root.mozTCPSocket;

        if (root.TCPSocket && typeof root.TCPSocket === "object") {
            // TCPSocket is already defined
            return root.TCPSocket;
        }
    }

    if (net && tls) {
        // node.js -> use native net/tls impl
        nodeShim();
    } else if (typeof chrome !== 'undefined' && (chrome.socket || chrome.sockets)) {
        // chrome packaged app using chrome.socket
        chromeShim();
    } else if (typeof window === 'object' && typeof io === 'function') {
        // websocket proxy
        wsShim();
    }

    function nodeShim() {
        TCPSocket = function(config) {
            var self = this,
                netApi;

            config.options.useSecureTransport = (typeof config.options.useSecureTransport !== 'undefined') ? config.options.useSecureTransport : false;
            config.options.binaryType = config.options.binaryType || 'arraybuffer';

            // public flags
            self.host = config.host;
            self.port = config.port;
            self.ssl = config.options.useSecureTransport;
            self.bufferedAmount = 0;
            self.readyState = 'connecting';
            self.binaryType = config.options.binaryType;

            if (self.binaryType !== 'arraybuffer') {
                throw new Error('Only arraybuffers are supported!');
            }

            netApi = (self.ssl) ? tls : net;
            self._socket = netApi.connect(self.port, self.host, self._emit.bind(self, 'open'));

            // add all event listeners to the new socket
            self._attachListeners();
        };

        TCPSocket.prototype._attachListeners = function() {
            var self = this;

            self._socket.on('data', function(nodeBuf) {
                // convert node buffer to array buffer or string
                self._emit('data', toArrayBuffer(nodeBuf));
            });

            self._socket.on('error', function(error) {
                self._emit('error', error);
                self.close();
            });

            self._socket.on('end', self._emit.bind(self, 'close'));
        };

        TCPSocket.prototype._removeListeners = function() {
            this._socket.removeAllListeners('data');
            this._socket.removeAllListeners('end');
            this._socket.removeAllListeners('error');
        };

        //
        // API
        //

        TCPSocket.prototype.close = function() {
            this.readyState = 'closing';
            this._socket.end();
        };

        TCPSocket.prototype.send = function(data) {
            // convert data to string or node buffer
            this._socket.write(toBuffer(data), this._emit.bind(this, 'drain'));
        };

        TCPSocket.prototype.upgradeToSecure = function() {
            var self = this;

            if (self.ssl) {
                return;
            }

            // remove all event listeners from the old socket
            self._removeListeners();

            // replace the old socket with a shiny new tls socket
            self._socket = tls.connect({
                socket: self._socket
            }, function() {
                self.ssl = true;
            });

            // add all event listeners to the new socket
            self._attachListeners();
        };

        // node buffer -> array buffer
        function toArrayBuffer(buffer) {
            var view = new Uint8Array(buffer.length);
            for (var i = 0; i < buffer.length; ++i) {
                view[i] = buffer[i];
            }
            return view.buffer;
        }

        // array buffer -> node buffer
        function toBuffer(ab) {
            return new Buffer(new Uint8Array(ab));
        }

    } // end of nodeShim

    function chromeShim() {
        TCPSocket = function(config) {
            var self = this;

            config.options.useSecureTransport = (typeof config.options.useSecureTransport !== 'undefined') ? config.options.useSecureTransport : false;
            config.options.binaryType = config.options.binaryType || 'arraybuffer';

            // public flags
            self.host = config.host;
            self.port = config.port;
            self.ssl = false;
            self.bufferedAmount = 0;
            self.readyState = 'connecting';
            self.binaryType = config.options.binaryType;

            if (self.binaryType !== 'arraybuffer') {
                throw new Error('Only arraybuffers are supported!');
            }

            // internal flags
            self._socketId = 0;
            self._ca = config.options.ca;
            self._useTLS = config.options.useSecureTransport;
            self._useSTARTTLS = false;
            self._tlsWorkerPath = config.options.tlsWorkerPath;
            self._useLegacySocket = false;
            self._useForgeTls = false;

            // handles writes during starttls handshake, chrome socket only
            self._startTlsBuffer = [];
            self._startTlsHandshakeInProgress = false;

            chrome.runtime.getPlatformInfo(function(platformInfo) {

                //
                // FIX START
                //

                if (platformInfo.os.indexOf("cordova") !== -1) {
                    // chrome.sockets.tcp.secure is not functional on cordova
                    // https://github.com/MobileChromeApps/mobile-chrome-apps/issues/269
                    self._useLegacySocket = false;
                    self._useForgeTls = true;
                } else {
                    self._useLegacySocket = true;
                    self._useForgeTls = false;
                }

                //
                // FIX END
                //

                // fire up the socket
                if (self._useLegacySocket) {
                    self._createLegacySocket();
                } else {
                    self._createSocket();
                }
            });
        };

        /**
         * Creates a socket using the deprecated chrome.socket API
         */
        TCPSocket.prototype._createLegacySocket = function() {
            var self = this;

            chrome.socket.create('tcp', {}, function(createInfo) {
                self._socketId = createInfo.socketId;

                chrome.socket.connect(self._socketId, self.host, self.port, function(result) {
                    if (result !== 0) {
                        self.readyState = 'closed';
                        self._emit('error', new Error('Unable to connect'));
                        return;
                    }

                    self._onSocketConnected();
                });
            });
        };

        /**
         * Creates a socket using chrome.sockets.tcp
         */
        TCPSocket.prototype._createSocket = function() {
            var self = this;

            chrome.sockets.tcp.create({}, function(createInfo) {
                self._socketId = createInfo.socketId;

                // register for data events on the socket before connecting
                chrome.sockets.tcp.onReceive.addListener(function(readInfo) {
                    if (readInfo.socketId === self._socketId) {
                        // process the data available on the socket
                        self._onData(readInfo.data);
                    }
                });

                // register for data error on the socket before connecting
                chrome.sockets.tcp.onReceiveError.addListener(function(readInfo) {
                    if (readInfo.socketId === self._socketId) {
                        // socket closed remotely or broken
                        self.close();
                    }
                });

                chrome.sockets.tcp.connect(self._socketId, self.host, self.port, function(result) {
                    if (result < 0) {
                        self.readyState = 'closed';
                        self._emit('error', new Error('Unable to connect'));
                        return;
                    }

                    self._onSocketConnected();
                });
            });
        };

        /**
         * Invoked once a socket has been connected:
         * - Kicks off TLS handshake, if necessary
         * - Starts reading from legacy socket, if necessary
         */
        TCPSocket.prototype._onSocketConnected = function() {
            var self = this;

            // do an immediate TLS handshake if self._useTLS === true
            if (self._useTLS) {
                self._upgradeToSecure(function() {
                    if (!self._useForgeTls) {
                        // chrome.socket is up and running by now, while forge needs to be
                        // fed traffic and emits 'open' at a later point
                        self._emit('open');

                        // the tls handshake is done let's start reading from the legacy socket
                        if (self._useLegacySocket) {
                            self._readLegacySocket();
                        }
                    }
                });
            } else {
                // socket is up and running
                self._emit('open');
                if (self._useLegacySocket) {
                    self._readLegacySocket(); // let's start reading
                }
            }
        };

        /**
         * Handles the rough edges for differences between chrome.socket and chrome.sockets.tcp
         * for upgrading to a TLS connection with or without forge
         */
        TCPSocket.prototype._upgradeToSecure = function(callback) {
            var self = this;

            callback = callback || function() {};

            if (self._useForgeTls) {
                // setup the forge tls client or webworker as tls fallback
                createTls.bind(self)();
                callback();
            } else if (!self._useLegacySocket) {
                chrome.sockets.tcp.secure(self._socketId, onUpgraded);
            } else if (self._useLegacySocket) {
                chrome.socket.secure(self._socketId, onUpgraded);
            }

            // invoked after chrome.socket.secure or chrome.sockets.tcp.secure have been upgraded
            function onUpgraded(tlsResult) {
                if (tlsResult !== 0) {
                    self._emit('error', new Error('TLS handshake failed. Reason: ' + chrome.runtime.lastError));
                    self.close();
                    return;
                }

                self.ssl = true;

                // empty the buffer
                while (self._startTlsBuffer.length) {
                    self.send(self._startTlsBuffer.shift());
                }

                callback();
            }
        };

        TCPSocket.prototype.upgradeToSecure = function() {
            var self = this;

            if (self.ssl || self._useSTARTTLS) {
                return;
            }

            self._useSTARTTLS = true;
            self._upgradeToSecure(function() {
                if (self._useLegacySocket) {
                    self._readLegacySocket(); // tls handshake is done, restart reading
                }
            });
        };

        /**
         * Reads from a legacy chrome.socket.
         */
        TCPSocket.prototype._readLegacySocket = function() {
            var self = this;

            if (self._socketId === 0) {
                // the socket is closed. omit read and stop further reads
                return;
            }

            // don't read from chrome.socket if we have chrome.socket.secure a handshake in progress!
            if ((self._useSTARTTLS || self._useTLS) && !self.ssl) {
                return;
            }

            chrome.socket.read(self._socketId, function(readInfo) {
                // socket closed remotely or broken
                if (readInfo.resultCode <= 0) {
                    self._socketId = 0;
                    self.close();
                    return;
                }

                // process the data available on the socket
                self._onData(readInfo.data);

                // queue the next read
                self._readLegacySocket();
            });
        };

        /**
         * Invoked when data has been read from the socket. Handles cases when to feed
         * the data available on the socket to forge.
         *
         * @param {ArrayBuffer} buffer The binary data read from the socket
         */
        TCPSocket.prototype._onData = function(buffer) {
            var self = this;

            if ((self._useTLS || self._useSTARTTLS) && self._useForgeTls) {
                // feed the data to the tls client
                if (self._tlsWorker) {
                    self._tlsWorker.postMessage(createMessage(EVENT_INBOUND, buffer), [buffer]);
                } else {
                    self._tls.processInbound(buffer);
                }
            } else {
                // emit data event
                self._emit('data', buffer);
            }
        };

        /**
         * Closes the socket
         * @return {[type]} [description]
         */
        TCPSocket.prototype.close = function() {
            this.readyState = 'closing';

            if (this._socketId !== 0) {
                if (this._useLegacySocket) {
                    // close legacy socket
                    chrome.socket.disconnect(this._socketId);
                    chrome.socket.destroy(this._socketId);
                } else {
                    // close socket
                    chrome.sockets.tcp.disconnect(this._socketId);
                }

                this._socketId = 0;
            }

            // terminate the tls worker
            if (this._tlsWorker) {
                this._tlsWorker.terminate();
                this._tlsWorker = undefined;
            }

            this._emit('close');
        };

        TCPSocket.prototype.send = function(buffer) {
            if (!this._useForgeTls && this._useSTARTTLS && !this.ssl) {
                // buffer the unprepared data until chrome.socket(s.tcp) handshake is done
                this._startTlsBuffer.push(buffer);
            } else if (this._useForgeTls && (this._useTLS || this._useSTARTTLS)) {
                // give buffer to forge to be prepared for tls
                if (this._tlsWorker) {
                    this._tlsWorker.postMessage(createMessage(EVENT_OUTBOUND, buffer), [buffer]);
                } else {
                    this._tls.prepareOutbound(buffer);
                }
            } else {
                // send the arraybuffer
                this._send(buffer);
            }
        };

        TCPSocket.prototype._send = function(data) {
            var self = this;

            if (self._socketId === 0) {
                // the socket is closed.
                return;
            }

            if (self._useLegacySocket) {
                chrome.socket.write(self._socketId, data, function(writeInfo) {
                    if (writeInfo.bytesWritten < 0 && self._socketId !== 0) {
                        // if the socket is already 0, it has already been closed. no need to alert then...
                        self._emit('error', new Error('Could not write ' + data.byteLength + ' bytes to socket ' + self._socketId + '. Chrome error code: ' + writeInfo.bytesWritten));
                        self._socketId = 0;
                        self.close();

                        return;
                    }

                    self._emit('drain');
                });
            } else {
                chrome.sockets.tcp.send(self._socketId, data, function(sendInfo) {
                    if (sendInfo.bytesSent < 0 && self._socketId !== 0) {
                        // if the socket is already 0, it has already been closed. no need to alert then...
                        self._emit('error', new Error('Could not write ' + data.byteLength + ' bytes to socket ' + self._socketId + '. Chrome error code: ' + sendInfo.bytesSent));
                        self.close();

                        return;
                    }

                    self._emit('drain');
                });
            }
        };
    } // end of chromeShim

    function wsShim() {
        TCPSocket = function(config) {
            var self = this;

            config.options.useSecureTransport = (typeof config.options.useSecureTransport !== 'undefined') ? config.options.useSecureTransport : false;
            config.options.binaryType = config.options.binaryType || 'arraybuffer';

            // public flags
            self.host = config.host;
            self.port = config.port;
            self.ssl = false;
            self.bufferedAmount = 0;
            self.readyState = 'connecting';
            self.binaryType = config.options.binaryType;

            if (self.binaryType !== 'arraybuffer') {
                throw new Error('Only arraybuffers are supported!');
            }

            // internal flags
            self._ca = config.options.ca;
            self._useTLS = config.options.useSecureTransport;
            self._useSTARTTLS = false;
            self._tlsWorkerPath = config.options.tlsWorkerPath;

            self._wsHost = (config.options.ws && config.options.ws.url) || window.location.origin;
            self._wsOptions = (config.options.ws && config.options.ws.options) || {};
            self._wsOptions.reconnection = self._wsOptions.reconnection || false;
            self._wsOptions.multiplex = self._wsOptions.multiplex || false;

            self._socket = io(self._wsHost, self._wsOptions);
            self._socket.emit('open', {
                host: self.host,
                port: self.port
            }, function(proxyHostname) {
                self._proxyHostname = proxyHostname;
                if (self._useTLS) {
                    // the socket is up, do the tls handshake
                    createTls.bind(self)();
                } else {
                    // socket is up and running
                    self._emit('open', {
                        proxyHostname: self._proxyHostname
                    });
                }

                self._socket.on('data', function(buffer) {
                    if (self._useTLS || self._useSTARTTLS) {
                        // feed the data to the tls socket
                        if (self._tlsWorker) {
                            self._tlsWorker.postMessage(createMessage(EVENT_INBOUND, buffer), [buffer]);
                        } else {
                            self._tls.processInbound(buffer);
                        }
                    } else {
                        // emit data event
                        self._emit('data', buffer);
                    }
                });

                self._socket.on('error', function(message) {
                    self._emit('error', new Error(message));
                    self.close();
                });

                self._socket.on('close', function() {
                    self.close();
                });
            });
        };

        //
        // API
        //

        TCPSocket.prototype.close = function() {
            this.readyState = 'closing';

            this._socket.emit('end');
            this._socket.disconnect();

            if (this._tlsWorker) {
                this._tlsWorker.terminate();
            }

            this._emit('close');
        };

        TCPSocket.prototype.send = function(buffer) {
            if (this._useTLS || this._useSTARTTLS) {
                // give buffer to forge to be prepared for tls
                if (this._tlsWorker) {
                    this._tlsWorker.postMessage(createMessage(EVENT_OUTBOUND, buffer), [buffer]);
                } else {
                    this._tls.prepareOutbound(buffer);
                }
                return;
            }

            // send the arraybuffer
            this._send(buffer);
        };

        TCPSocket.prototype._send = function(data) {
            var self = this;
            self._socket.emit('data', data, function() {
                self._emit('drain');
            });
        };

        TCPSocket.prototype.upgradeToSecure = function() {
            if (this.ssl || this._useSTARTTLS) {
                return;
            }

            this._useSTARTTLS = true;

            // setup the forge tls client or webworker
            createTls.bind(this)();
        };
    } // end of wsShim

    //
    // TLS shim event handlers, unused when native TLS
    //

    TCPSocket.prototype.tlscert = function(cert) {
        this.oncert(cert);
    };

    TCPSocket.prototype.tlserror = function(message) {
        this._emit('error', new Error(message));
        this.close();
    };

    TCPSocket.prototype.tlsclose = function() {
        this.close();
    };

    TCPSocket.prototype.tlsopen = function() {
        this.ssl = true;
        if (this._useTLS) {
            if (this._proxyHostname) {
                this._emit('open', {
                    proxyHostname: this._proxyHostname
                });
            } else {
                this._emit('open');
            }
        }
    };

    TCPSocket.prototype.tlsoutbound = function(buffer) {
        this._send(buffer);
    };

    TCPSocket.prototype.tlsinbound = function(buffer) {
        this._emit('data', buffer);
    };

    //
    // Common API
    //

    TCPSocket.open = function(host, port, options) {
        return new TCPSocket({
            host: host,
            port: port,
            options: options || {}
        });
    };

    TCPSocket.listen = TCPSocket.listen || apiNotSupported;
    TCPSocket.prototype.resume = TCPSocket.prototype.resume || apiNotSupported;
    TCPSocket.prototype.suspend = TCPSocket.prototype.suspend || apiNotSupported;
    TCPSocket.prototype.upgradeToSecure = TCPSocket.prototype.upgradeToSecure || apiNotSupported;

    function apiNotSupported() {
        throw new Error('API not supported');
    }

    //
    //
    // Internal use
    //
    //

    // utility function, to be bound to the respective websocket & chrome.socket shim TCPSocket object
    var createTls = function() {
        // create the respective TLS shim
        if (window.Worker && typeof this._tlsWorkerPath === 'string') {
            createTlsWorker.bind(this)();
        } else {
            // setup the forge tls client
            createTlsNoWorker.bind(this)();
        }
    };

    // utility function, to be bound to the TCPSocket object
    // creates an instance of the tls shim (no worker)
    var createTlsNoWorker = function() {
        // create the tls client
        this._tls = new TLS();

        // attach the handlers
        this._tls.tlserror = this.tlserror.bind(this);
        this._tls.tlscert = this.tlscert.bind(this);
        this._tls.tlsclose = this.tlsclose.bind(this);
        this._tls.tlsopen = this.tlsopen.bind(this);
        this._tls.tlsoutbound = this.tlsoutbound.bind(this);
        this._tls.tlsinbound = this.tlsinbound.bind(this);

        // configure the tls client
        this._tls.configure({
            host: this.host,
            ca: this._ca
        });

        // start the handshake
        this._tls.handshake();
    };

    // utility function, to be bound to the TCPSocket object
    // creates an instance of the tls shim running in a web worker
    var createTlsWorker = function() {
        var self = this,
            workerPath = self._tlsWorkerPath;

        self._tlsWorker = new Worker(workerPath);
        self._tlsWorker.onmessage = function(e) {
            var event = e.data.event,
                message = e.data.message;

            switch (event) {
                case EVENT_CERT:
                    self.tlscert(message);
                    break;

                case EVENT_ERROR:
                    self.tlserror(message);
                    break;

                case EVENT_CLOSE:
                    self.tlsclose(message);
                    break;

                case EVENT_OPEN:
                    self.tlsopen(message);
                    break;

                case EVENT_OUTBOUND:
                    self.tlsoutbound(message);
                    break;

                case EVENT_INBOUND:
                    self.tlsinbound(message);
                    break;
            }
        };

        self._tlsWorker.onerror = function(e) {
            var error = new Error('Error handling web worker: Line ' + e.lineno + ' in ' + e.filename + ': ' + e.message);
            console.error(error);
            self.tlserror(error.message);
        };

        // start the worker and configure the tls client
        self._tlsWorker.postMessage(createMessage(EVENT_CONFIG, {
            host: self.host,
            ca: self._ca
        }));

        // start the handshake
        self._tlsWorker.postMessage(createMessage(EVENT_HANDSHAKE));
    };

    function createMessage(event, message) {
        return {
            event: event,
            message: message
        };
    }

    TCPSocket.prototype._emit = function(type, data) {
        var cb;
        if (type === 'open') {
            this.readyState = 'open';
            cb = this.onopen;
        } else if (type === 'error') {
            cb = this.onerror;
        } else if (type === 'data') {
            cb = this.ondata;
        } else if (type === 'drain') {
            cb = this.ondrain;
        } else if (type === 'close') {
            this.readyState = 'closed';
            cb = this.onclose;
        }

        if (typeof cb !== 'function') {
            return;
        }

        cb({
            target: this,
            type: type,
            data: data
        });
    };

    if (root) {
        // add TCPSocket to root object
        root.TCPSocket = TCPSocket;
    }

    return TCPSocket;
});


text:
package io.fabric.samples.cannonball.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import com.crashlytics.android.Crashlytics;

public class DbHelper extends SQLiteOpenHelper {

    public DbHelper(Context context) {
        super(context, PoemContract.DB_NAME, null, PoemContract.DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(PoemContract.DATABASE_CREATE_POEMS);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Crashlytics.log(
                "Upgrading database from version " + oldVersion + " to "
                        + newVersion + ", which will destroy all old data"
        );
        db.execSQL("DROP TABLE IF EXISTS " + PoemContract.TABLE);
        this.onCreate(db);
    }
}

redpajama_set_name: RedPajamaGithub


text:
import { inject, injectable } from 'inversify';
import { Uri, WorkspaceConfiguration } from 'vscode';
import { IWorkspaceService } from '../../common/application/types';
import { Product } from '../../common/types';
import { IServiceContainer } from '../../ioc/types';
import { ITestConfigSettingsService, UnitTestProduct } from './types';

@injectable()
export class TestConfigSettingsService implements ITestConfigSettingsService {
    private readonly workspaceService: IWorkspaceService;

    constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) {
        this.workspaceService = serviceContainer.get<IWorkspaceService>(IWorkspaceService);
    }

    public async updateTestArgs(testDirectory: string | Uri, product: UnitTestProduct, args: string[]): Promise<void> {
        const setting = this.getTestArgSetting(product);
        return this.updateSetting(testDirectory, setting, args);
    }

    public async enable(testDirectory: string | Uri, product: UnitTestProduct): Promise<void> {
        const setting = this.getTestEnablingSetting(product);
        return this.updateSetting(testDirectory, setting, true);
    }

    public async disable(testDirectory: string | Uri, product: UnitTestProduct): Promise<void> {
        const setting = this.getTestEnablingSetting(product);
        return this.updateSetting(testDirectory, setting, false);
    }

    // eslint-disable-next-line class-methods-use-this
    public getTestEnablingSetting(product: UnitTestProduct): string {
        switch (product) {
            case Product.unittest:
                return 'testing.unittestEnabled';
            case Product.pytest:
                return 'testing.pytestEnabled';
            default:
                throw new Error('Invalid Test Product');
        }
    }

    // eslint-disable-next-line class-methods-use-this
    private getTestArgSetting(product: UnitTestProduct): string {
        switch (product) {
            case Product.unittest:
                return 'testing.unittestArgs';
            case Product.pytest:
                return 'testing.pytestArgs';
            default:
                throw new Error('Invalid Test Product');
        }
    }

    private async updateSetting(testDirectory: string | Uri, setting: string, value: unknown) {
        let pythonConfig: WorkspaceConfiguration;
        const resource = typeof testDirectory === 'string' ? Uri.file(testDirectory) : testDirectory;
        const hasWorkspaceFolders = (this.workspaceService.workspaceFolders?.length || 0) > 0;
        if (!hasWorkspaceFolders) {
            pythonConfig = this.workspaceService.getConfiguration('python');
        } else if (this.workspaceService.workspaceFolders!.length === 1) {
            pythonConfig = this.workspaceService.getConfiguration(
                'python',
                this.workspaceService.workspaceFolders![0].uri,
            );
        } else {
            const workspaceFolder = this.workspaceService.getWorkspaceFolder(resource);
            if (!workspaceFolder) {
                throw new Error(`Test directory does not belong to any workspace (${testDirectory})`);
            }

            pythonConfig = this.workspaceService.getConfiguration('python', workspaceFolder.uri);
        }

        return pythonConfig.update(setting, value);
    }
}


text:
package org.luciddb.lcs;

import org.luciddb.session.*;

import java.math.*;

import java.util.*;

import net.sf.farrago.catalog.*;
import net.sf.farrago.cwm.keysindexes.*;
import net.sf.farrago.cwm.relational.*;
import net.sf.farrago.fem.fennel.*;
import net.sf.farrago.fem.med.*;
import net.sf.farrago.fem.sql2003.*;
import net.sf.farrago.fennel.*;
import net.sf.farrago.fennel.rel.*;
import net.sf.farrago.fennel.tuple.*;
import net.sf.farrago.query.*;
import net.sf.farrago.resource.*;
import net.sf.farrago.type.*;

import org.eigenbase.jmi.*;
import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
import org.eigenbase.sarg.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.util.*;

/**
 * LcsIndexGuide provides information about the mapping from catalog definitions
 * for LCS tables and their clusters to their Fennel representation.
 *
 * @author Zelaine Fong
 * @version $Id$
 */
public class LcsIndexGuide
{
    //~ Static fields/initializers ---------------------------------------------

    public static final int LbmBitmapSegMaxSize = 512;

    //~ Instance fields --------------------------------------------------------

    private FarragoTypeFactory typeFactory;

    private FarragoRepos repos;

    private CwmColumnSet table;

    private RelDataType unflattenedRowType;

    private RelDataType flattenedRowType;

    private int [] flatteningMap;

    private List<FemLocalIndex> clusteredIndexes;

    private List<Integer> clusterMap;

    private int numFlattenedCols;

    private int numUnFlattenedCols;

    private Map<FemLocalIndex, Integer> clusterToRootPageIdParamIdMap;

    private Map<Integer, FemLocalIndex> ordinalToClusterMap;

    //~ Constructors -----------------------------------------------------------

    /**
     * Construct an IndexGuide using a specific list of clustered indexes
     *
     * @param typeFactory
     * @param table the column store table
     * @param clusteredIndexes list of clustered indexes
     */
    LcsIndexGuide(
        FarragoTypeFactory typeFactory,
        CwmColumnSet table,
        List<FemLocalIndex> clusteredIndexes)
    {
        this.typeFactory = typeFactory;
        repos = typeFactory.getRepos();

        this.table = table;

        unflattenedRowType = typeFactory.createStructTypeFromClassifier(table);
        numUnFlattenedCols = unflattenedRowType.getFieldList().size();
        flatteningMap = new int[numUnFlattenedCols];

        flattenedRowType =
            SqlTypeUtil.flattenRecordType(
                typeFactory,
                unflattenedRowType,
                flatteningMap);
        numFlattenedCols = flattenedRowType.getFieldList().size();

        this.clusteredIndexes = clusteredIndexes;

        clusterToRootPageIdParamIdMap = new HashMap<FemLocalIndex, Integer>();

        createClusterMap(clusteredIndexes);

        // Create a mapping from flattened ordinal to its corresponding cluster
        ordinalToClusterMap = new HashMap<Integer, FemLocalIndex>();
        for (FemLocalIndex cluster : clusteredIndexes) {
            for (CwmIndexedFeature indexedFeature
                : cluster.getIndexedFeature())
            {
                FemAbstractColumn column =
                    (FemAbstractColumn) indexedFeature.getFeature();
                int start = flattenOrdinal(column.getOrdinal());
                int end = start + getNumFlattenedSubCols(column.getOrdinal());
                for (int i = start; i < end; i++) {
                    ordinalToClusterMap.put(i, cluster);
                }
            }
        }
    }

    /**
     * Construct an IndexGuide using the default list of indexes
     *
     * @param typeFactory
     * @param table the column store table
     */
    LcsIndexGuide(
        FarragoTypeFactory typeFactory,
        CwmColumnSet table)
    {
        this(
            typeFactory,
            table,
            FarragoCatalogUtil.getClusteredIndexes(
                typeFactory.getRepos(),
                table));
    }

    /**
     * Construct an IndexGuide using an unclustered index
     *
     * @param typeFactory
     * @param table the column store table
     * @param unclusteredIndex an unclustered index
     */
    LcsIndexGuide(
        FarragoTypeFactory typeFactory,
        CwmColumnSet table,
        FemLocalIndex unclusteredIndex)
    {
        this(
            typeFactory,
            table,
            getIndexCoverageSet(
                typeFactory.getRepos(),
                unclusteredIndex,
                FarragoCatalogUtil.getClusteredIndexes(
                    typeFactory.getRepos(),
                    table),
                true,
                true));
    }

    //~ Methods ----------------------------------------------------------------

    /**
     * Determines the list of indexes from a candidate index list those indexes
     * that contain at least one column matching the columns of a specified
     * index.
     *
     * @param repos repository
     * @param index the specified index
     * @param candidateIndexes candidate indexes
     * @param singleMatch if true, find only the first candidate index that
     * covers each column in the specified index; otherwise, find all candidate
     * indexes that cover each column
     * @param requireNonEmpty if true, the return list must be non-empty
     *
     * @return the list of indexes from the candidate list covering the
     * specified index
     */
    public static List<FemLocalIndex> getIndexCoverageSet(
        FarragoRepos repos,
        FemLocalIndex index,
        List<FemLocalIndex> candidateIndexes,
        boolean singleMatch,
        boolean requireNonEmpty)
    {
        //
        // Get the columns of the specified index
        //
        Set<CwmColumn> requiredColumns = new HashSet<CwmColumn>();
        for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
            requiredColumns.add((CwmColumn) indexedFeature.getFeature());
        }

        //
        // Find the candidate indexes which cover the columns of the index
        //
        List<FemLocalIndex> coverageIndexes = new ArrayList<FemLocalIndex>();
        for (FemLocalIndex candidateIndex : candidateIndexes) {
            boolean include = false;
            for (
                CwmIndexedFeature indexedFeature
                : candidateIndex.getIndexedFeature())
            {
                CwmColumn column = (CwmColumn) indexedFeature.getFeature();
                if (requiredColumns.contains(column)) {
                    include = true;
                    if (singleMatch) {
                        requiredColumns.remove(column);
                    }
                }
            }
            if (include) {
                coverageIndexes.add(candidateIndex);
            }
        }

        if (requireNonEmpty && !requiredColumns.isEmpty()) {
            throw Util.newInternal("index could not be covered");
        }

        return coverageIndexes;
    }

    /**
     * @return the flattened row type for the indexed table
     */
    public RelDataType getFlattenedRowType()
    {
        return flattenedRowType;
    }

    /**
     * Creates an array mapping cluster columns to table columns, the order of
     * the array matching the order of the cluster columns in an ordered list of
     * clusters. E.g.,
     *
     *

     *
     * create table t(a int, b int, c int, d int);
     * create clustered index it_c on t(c);
     * create clustered index it_ab on t(a, b);
     * create clustered index it_d on t(d);
     *
     * clusterMap[] = { 2, 0, 1, 3 }
     *
     *

     *
     * @param clusteredIndexes ordered list of clusters
     */
    private void createClusterMap(List<FemLocalIndex> clusteredIndexes)
    {
        clusterMap = new ArrayList<Integer>();

        for (FemLocalIndex index : clusteredIndexes) {
            for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
                FemAbstractColumn column =
                    (FemAbstractColumn) indexedFeature.getFeature();
                addClusterCols(column.getOrdinal());
            }
        }
    }

    /**
     * Flattens a column and adds an entry for each subcolumn within the
     * flattened column into clusterMap
     *
     * @param colOrdinal 0-based ordinal representing an unflattened column
     */
    private void addClusterCols(int colOrdinal)
    {
        int nColsToAdd = getNumFlattenedSubCols(colOrdinal);

        colOrdinal = flattenOrdinal(colOrdinal);

        for (int i = colOrdinal; i < (colOrdinal + nColsToAdd); i++) {
            clusterMap.add(i);
        }
    }

    /**
     * Returns number of subcolumns corresponding to a column once it is
     * flattened.
     *
     * @param colOrdinal 0-based ordinal representing an unflattened column
     *
     * @return number of subcolumns in flattened column
     */
    public int getNumFlattenedSubCols(int colOrdinal)
    {
        int nCols;

        if (colOrdinal == (numUnFlattenedCols - 1)) {
            nCols = numFlattenedCols - flatteningMap[colOrdinal];
        } else {
            nCols = flatteningMap[colOrdinal + 1] - flatteningMap[colOrdinal];
        }
        return nCols;
    }

    /**
     * Retrieves number of columns in a clustered index
     *
     * @param index the clustered index
     *
     * @return number of columns
     */
    public int getNumFlattenedClusterCols(FemLocalIndex index)
    {
        int nCols = 0;

        assert (index.isClustered());
        for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
            FemAbstractColumn column =
                (FemAbstractColumn) indexedFeature.getFeature();
            nCols += getNumFlattenedSubCols(column.getOrdinal());
        }
        return nCols;
    }

    /**
     * Retrieves number of columns in all the clustered indexes accessed
     *
     * @return number of columns
     */
    public int getNumFlattenedClusterCols()
    {
        int nCols = 0;

        for (FemLocalIndex index : clusteredIndexes) {
            for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
                FemAbstractColumn column =
                    (FemAbstractColumn) indexedFeature.getFeature();
                nCols += getNumFlattenedSubCols(column.getOrdinal());
            }
        }
        return nCols;
    }

    /**
     * Creates a tuple descriptor corresponding to a clustered index
     *
     * @param index clustered index
     *
     * @return tuple descriptor for cluster
     */
    public FemTupleDescriptor getClusterTupleDesc(FemLocalIndex index)
    {
        FemTupleDescriptor tupleDesc = repos.newFemTupleDescriptor();
        List<RelDataTypeField> flattenedColList =
            flattenedRowType.getFieldList();

        for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
            FemAbstractColumn column =
                (FemAbstractColumn) indexedFeature.getFeature();
            int numSubCols = getNumFlattenedSubCols(column.getOrdinal());
            int colOrd = flattenOrdinal(column.getOrdinal());

            // add an entry for each subcolumn within a complex type
            for (int i = colOrd; i < (colOrd + numSubCols); i++) {
                RelDataTypeField field = flattenedColList.get(i);
                FennelRelUtil.addTupleAttrDescriptor(
                    repos,
                    tupleDesc,
                    field.getType());
            }
        }
        return tupleDesc;
    }

    /**
     * Creates a projection list relative to the cluster columns
     *
     * @param origProj original projection list relative to the table; if null,
     * project all columns from table
     *
     * @return projection list created
     */
    public Integer [] computeProjectedColumns(Integer [] origProj)
    {
        Integer [] proj;
        int i;

        // use the inverse of the cluster map to locate the corresponding
        // cluster column number
        if (origProj != null) {
            proj = new Integer[origProj.length];
            for (i = 0; i < origProj.length; i++) {
                proj[i] = computeProjectedColumn(origProj[i].intValue());
            }
        } else {
            proj = new Integer[numFlattenedCols];
            for (i = 0; i < proj.length; i++) {
                proj[i] = computeProjectedColumn(i);
            }
        }
        return proj;
    }

    private Integer computeProjectedColumn(int i)
    {
        if (LucidDbOperatorTable.ldbInstance().isSpecialColumnId(i)) {
            return new Integer(i);
        } else {
            int j = clusterMap.indexOf(i);
            assert (j != -1);
            return new Integer(j);
        }
    }

    /**
     * Determines if an index is referenced by projection list
     *
     * @param index clustered index being checked
     * @param projection array of flattened ordinals of projected columns
     *
     * @return true if at least one column in the clustered index is referenced
     * in the projection list
     */
    public boolean testIndexCoverage(
        FemLocalIndex index,
        Integer [] projection)
    {
        for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
            FemAbstractColumn column =
                (FemAbstractColumn) indexedFeature.getFeature();
            if (testColumnCoverage(column, projection)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Determines if a column is referenced by projection list.
     *
     * @param column column being checked
     * @param projection array of flattened ordinals of projected columns
     *
     * @return true if the column (or one of its sub-fields for a column with
     * structured type) is referenced in the projection list
     */
    public boolean testColumnCoverage(
        FemAbstractColumn column,
        Integer [] projection)
    {
        int n = flattenOrdinal(column.getOrdinal());
        int nEnd = n + getNumFlattenedSubCols(column.getOrdinal());
        for (int i = 0; i < projection.length; i++) {
            if ((projection[i] >= n) && (projection[i] < nEnd)) {
                return true;
            }
        }
        return false;
    }

    private int flattenOrdinal(int columnOrdinal)
    {
        int i = flatteningMap[columnOrdinal];
        assert (i != -1);
        return i;
    }

    /**
     * Returns the unflattened column ordinal corresponding to a flattened field
     * ordinal
     *
     * @param fieldOrdinal flattened ordinal
     *
     * @return unflattened ordinal
     */
    public int unFlattenOrdinal(int fieldOrdinal)
    {
        int columnOrdinal = Arrays.binarySearch(flatteningMap, fieldOrdinal);
        if (columnOrdinal >= 0) {
            return columnOrdinal;
        } else {
            // When an inexact match is found, binarySearch returns
            // (-(insertion point) - 1).  We want (insertion point) - 1.
            return -(columnOrdinal + 1) - 1;
        }
    }

    /**
     * Creates a tuple descriptor for the BTree index corresponding to a
     * clustered index. For LCS clustered indexes, the stored tuple is always
     * the same: [RID, PageId]; and the key is just the RID. In Fennel, both
     * attributes are represented as 64-bit ints.
     *
     * @return btree tuple descriptor
     */
    public FemTupleDescriptor createClusteredBTreeTupleDesc()
    {
        FemTupleDescriptor tupleDesc = repos.newFemTupleDescriptor();

        // add RID
        appendInt64Attr(tupleDesc);

        // add PageId
        appendInt64Attr(tupleDesc);

        return tupleDesc;
    }

    private void appendInt64Attr(FemTupleDescriptor tupleDesc)
    {
        FennelStoredTypeDescriptor typeDesc =
            FennelStandardTypeDescriptor.INT_64;
        FemTupleAttrDescriptor attrDesc = repos.newFemTupleAttrDescriptor();
        tupleDesc.getAttrDescriptor().add(attrDesc);
        attrDesc.setTypeOrdinal(typeDesc.getOrdinal());
    }

    private void appendBitmapAttr(FemTupleDescriptor tupleDesc)
    {
        FennelStoredTypeDescriptor typeDesc =
            FennelStandardTypeDescriptor.VARBINARY;
        FemTupleAttrDescriptor attrDesc = repos.newFemTupleAttrDescriptor();
        tupleDesc.getAttrDescriptor().add(attrDesc);
        attrDesc.setTypeOrdinal(typeDesc.getOrdinal());
        attrDesc.setNullable(true);

        // REVIEW jvs 6-Jan-2006: this is based on a 32K page size with a
        // maximum entry size of 1/8 of a page.  Should probably make it
        // communicate with native code about this to get the right number
        // automatically.
        attrDesc.setByteLength(LbmBitmapSegMaxSize);
    }

    // TODO jvs 6-Jan-2005:  use this in LcsTableAppendRel.

    /**
     * Creates a tuple projection for the RID attribute of the BTree index
     * corresponding to a clustered index.
     *
     * @return RID attribute projection
     *
     * @see #createClusteredBTreeTupleDesc
     */
    public FemTupleProjection createClusteredBTreeRidDesc()
    {
        return FennelRelUtil.createTupleProjection(
            repos,
            new Integer[] { 0 });
    }

    /**
     * Creates a tuple projection for the PageId attribute of the BTree index
     * tuple corresponding to a clustered index.
     *
     * @return PageId attribute projection
     *
     * @see #createClusteredBTreeTupleDesc
     */
    public FemTupleProjection createClusteredBTreePageIdDesc()
    {
        return FennelRelUtil.createTupleProjection(
            repos,
            new Integer[] { 1 });
    }

    /**
     * Creates a tuple descriptor for the BTree index corresponding to an
     * unclustered index.
     *
     *
For LCS unclustered indexes, the stored tuple is [K1, K2, ..., RID,
     * BITMAP, BITMAP], and the key is [K1, K2, ..., RID]
     *
     * @param index unclustered index
     *
     * @return btree tuple descriptor
     */
    public FemTupleDescriptor createUnclusteredBTreeTupleDesc(
        FemLocalIndex index)
    {
        assert (!index.isClustered());

        FemTupleDescriptor tupleDesc = repos.newFemTupleDescriptor();

        // add K1, K2, ...
        for (CwmIndexedFeature indexedFeature : index.getIndexedFeature()) {
            FemAbstractColumn column =
                (FemAbstractColumn) indexedFeature.getFeature();
            FennelRelUtil.addTupleAttrDescriptor(
                repos,
                tupleDesc,
                typeFactory.createCwmElementType(column));
        }

        // add RID
        appendInt64Attr(tupleDesc);

        // add BITMAP
        appendBitmapAttr(tupleDesc);
        appendBitmapAttr(tupleDesc);

        return tupleDesc;
    }

    public FemTupleDescriptor createUnclusteredBTreeBitmapDesc()
    {
        FemTupleDescriptor tupleDesc = repos.newFemTupleDescriptor();

        // add RID
        appendInt64Attr(tupleDesc);

        // add BITMAP
        appendBitmapAttr(tupleDesc);
        appendBitmapAttr(tupleDesc);

        return tupleDesc;
    }

    /**
     * Creates a tuple projection for the key attributes of the BTree index
     * corresponding to an unclustered index.
     *
     * @param index unclustered index
     *
     * @return key attribute projection
     *
     * @see #createUnclusteredBTreeTupleDesc
     */
    public FemTupleProjection createUnclusteredBTreeKeyProj(
        FemLocalIndex index)
    {
        // number of key fields = number of columns plus RID
        int n = index.getIndexedFeature().size() + 1;

        return FennelRelUtil.createTupleProjection(
            repos,
            FennelRelUtil.newIotaProjection(n));
    }

    public FemTupleProjection createUnclusteredBTreeBitmapProj(
        FemLocalIndex index)
    {
        List<Integer> bitmapProj = new ArrayList<Integer>();

        // bitmap tuple format is
        //    [key0, key1..., keyN, RID, SegmentDesc, Segment]
        // the bitmap fields are:
        //                         {RID, SegmentDesc, Segment]
        int startPos = index.getIndexedFeature().size();

        bitmapProj.add(startPos);
        bitmapProj.add(startPos + 1);
        bitmapProj.add(startPos + 2);

        return FennelRelUtil.createTupleProjection(
            repos,
            bitmapProj);
    }

    /**
     * Creates a row data type for a projection of an index. The projection may
     * include both key columns and bitmap columns.
     *
     * @param index the index to be projected
     * @param proj a projection on the index
     *
     * @return row data type based on projections of an index
     *
     * @see #createUnclusteredBTreeTupleDesc
     */
    public RelDataType createUnclusteredRowType(
        FemLocalIndex index,
        Integer [] proj)
    {
        List<CwmIndexedFeature> indexFeatures = index.getIndexedFeature();
        int nKeys = indexFeatures.size();
        RelDataType bitmapRowType = createUnclusteredBitmapRowType();

        if (proj == null) {
            return bitmapRowType;
        }

        RelDataType [] types = new RelDataType[proj.length];
        String [] names = new String[proj.length];
        for (int i = 0; i < proj.length; i++) {
            int j = proj[i];
            if (j < nKeys) {
                FemAbstractColumn column =
                    (FemAbstractColumn) indexFeatures.get(j).getFeature();
                names[i] = column.getName();
                types[i] = typeFactory.createCwmElementType(column);
            } else {
                names[i] = bitmapRowType.getFields()[j - nKeys].getName();
                types[i] = bitmapRowType.getFields()[j - nKeys].getType();
            }
        }
        return typeFactory.createStructType(types, names);
    }

    /**
     * Creates the row data type of error records produced by a splicer when
     * there unique constraint violations. The row type generated contains the
     * same column types as the btree key [K1, K2, ..., RID]
     *
     * @param uniqueIndex the unique index updated by the splicer
     *
     * @return row data type for splicer error records
     */
    public RelDataType createSplicerErrorType(FemLocalIndex uniqueIndex)
    {
        // get projections for [keys ..., rid]
        int nKeys = uniqueIndex.getIndexedFeature().size();
        Integer [] keyProj = FennelRelUtil.newIotaProjection(nKeys + 1);
        return createUnclusteredRowType(uniqueIndex, keyProj);
    }

    FemSplitterStreamDef newSplitter(RelDataType outputRowType)
    {
        FemSplitterStreamDef splitter = repos.newFemSplitterStreamDef();

        splitter.setOutputDesc(
            FennelRelUtil.createTupleDescriptorFromRowType(
                repos,
                typeFactory,
                outputRowType));
        return splitter;
    }

    FemBarrierStreamDef newBarrier(
        RelDataType outputRowType,
        BarrierReturnMode returnMode,
        int deleteRowCountParamId)
    {
        FemBarrierStreamDef barrier = repos.newFemBarrierStreamDef();

        // returnMode indicates which input stream or streams contain the
        // data that the barrier should produce
        barrier.setReturnMode(returnMode);

        // if this is the final barrier in a MERGE statement, setup the
        // barrier to receive the upstream deletion rowcount
        if (deleteRowCountParamId > 0) {
            FemDynamicParameter dynParam = repos.newFemDynamicParameter();
            dynParam.setParameterId(deleteRowCountParamId);
            barrier.getDynamicParameter().add(dynParam);
        }

        barrier.setOutputDesc(
            FennelRelUtil.createTupleDescriptorFromRowType(
                repos,
                typeFactory,
                outputRowType));

        return barrier;
    }

    /**
     * Creates a cluster append stream for a specific clustered index.
     *
     * @param rel the RelNode that the cluster belongs to
     * @param clusterIndex the clustered index
     * @param hasIndexes if true, indexes will also be inserted into as part of
     * execution of this cluster append
     * @param rootPageIdParamId the dynamic parameter id of the root page of the
     * cluster; only set > 0 if this is a cluster replace
     * @param clusterPos only used if this is a cluster replace, in which case,
     * it corresponds to the position of this cluster from the list of clusters
     * that will be replaced
     * @param alterTable whether we are doing ALTER TABLE ADD COLUMN
     *
     * @return the constructed cluster append stream
     */
    FemLcsClusterAppendStreamDef newClusterAppend(
        FennelRel rel,
        FemLocalIndex clusterIndex,
        boolean hasIndexes,
        int rootPageIdParamId,
        int clusterPos,
        boolean alterTable)
    {
        FemLcsClusterAppendStreamDef clusterAppend;
        if (rootPageIdParamId > 0) {
            clusterAppend = repos.newFemLcsClusterReplaceStreamDef();
        } else {
            clusterAppend = repos.newFemLcsClusterAppendStreamDef();
        }

        defineIndexStream(
            clusterAppend,
            rel,
            clusterIndex,
            true,
            true,
            rootPageIdParamId);

        //
        // Set up FemLcsClusterAppendStreamDef
        //        - setClusterColProj
        //

        Integer [] clusterColProj;
        if (rootPageIdParamId > 0) {
            // The rid column always appears first in the input tuple and
            // is projected as the first column, followed by the only column
            // in the cluster.
            clusterColProj = new Integer[2];
            clusterColProj[0] = 0;
            clusterColProj[1] = clusterPos;

            // Keep track of the dynamic parameter for later use
            clusterToRootPageIdParamIdMap.put(clusterIndex, rootPageIdParamId);
        } else {
            clusterColProj =
                new Integer[getNumFlattenedClusterCols(clusterIndex)];

            //
            // Figure out the projection covering columns contained in each
            // index.
            //
            int i = 0;
            for (
                CwmIndexedFeature indexedFeature
                : clusterIndex.getIndexedFeature())
            {
                FemAbstractColumn column =
                    (FemAbstractColumn) indexedFeature.getFeature();
                int n = getNumFlattenedSubCols(column.getOrdinal());
                for (int j = 0; j < n; ++j) {
                    if (alterTable) {
                        // If we're doing ALTER TABLE ADD COLUMN, the
                        // new column is the only thing in the input;
                        // if it's a UDT, its fields should match the
                        // order of the input row.
                        clusterColProj[i] = i;
                    } else {
                        clusterColProj[i] =
                            flattenOrdinal(column.getOrdinal()) + j;
                    }
                    i++;
                }
            }
        }

        clusterAppend.setClusterColProj(
            FennelRelUtil.createTupleProjection(repos, clusterColProj));
        if (hasIndexes) {
            clusterAppend.setOutputDesc(getUnclusteredInputDesc());
        }

        return clusterAppend;
    }

    FemLcsRowScanStreamDef newRowScan(
        LcsRowScanRelBase rel,
        Integer [] projectedColumns,
        Integer [] residualColumns)
    {
        FemLcsRowScanStreamDef scanStream;
        if (rel instanceof LcsRowAggRel) {
            scanStream = repos.newFemLcsAggStreamDef();
        } else {
            scanStream = repos.newFemLcsRowScanStreamDef();
        }

        defineScanStream(scanStream, rel, false);

        // setup the output projection relative to the ordered list of
        // clustered indexes
        Integer [] clusterProjection =
            computeProjectedColumns(projectedColumns);
        scanStream.setOutputProj(
            FennelRelUtil.createTupleProjection(repos, clusterProjection));
        scanStream.setFullScan(rel.isFullScan);
        scanStream.setHasExtraFilter(rel.hasResidualFilters());
        scanStream.setSamplingMode(TableSamplingModeEnum.SAMPLING_OFF);
        Integer [] clusterResidualColumns =
            computeProjectedColumns(residualColumns);

        scanStream.setResidualFilterColumns(
            FennelRelUtil.createTupleProjection(repos, clusterResidualColumns));
        return scanStream;
    }

    /**
     * Creates a set of streams for updating a bitmap index
     */
    LcsCompositeStreamDef newBitmapAppend(
        FennelRel rel,
        FemLocalIndex index,
        FemLocalIndex deletionIndex,
        FennelRelImplementor implementor,
        boolean createIndex,
        FennelRelParamId insertDynParamId,
        boolean createNewIndex)
    {
        // create the streams
        FemExecutionStreamDef generator =
            newGenerator(
                rel,
                index,
                createIndex,
                implementor.translateParamId(insertDynParamId).intValue());

        // do an early close in the sorter, in case there was an upstream
        // insert into the deletion index, which the splicer may need to read
        FemExecutionStreamDef sorter = newSorter(index, null, false, true);
        FemExecutionStreamDef splicer =
            newSplicer(
                rel,
                index,
                deletionIndex,
                implementor.translateParamId(insertDynParamId).intValue(),
                0,
                createNewIndex);

        // link them up
        implementor.addDataFlowFromProducerToConsumer(generator, sorter);
        implementor.addDataFlowFromProducerToConsumer(sorter, splicer);

        return new LcsCompositeStreamDef(generator, splicer);
    }

    private FemLbmGeneratorStreamDef newGenerator(
        FennelRel rel,
        FemLocalIndex index,
        boolean createIndex,
        int insertRowCountParamId)
    {
        FemLbmGeneratorStreamDef generator =
            repos.newFemLbmGeneratorStreamDef();

        //
        // Setup cluster scans. The generator scans are based on the new
        // clusters being written.
        //
        defineScanStream(generator, rel, true);

        //
        // Setup projection used by unclustered index
        //
        List<CwmIndexedFeature> indexFeatures = index.getIndexedFeature();
        Integer [] indexProjection = new Integer[indexFeatures.size()];
        int i = 0;
        for (CwmIndexedFeature feature : indexFeatures) {
            FemAbstractColumn column = (FemAbstractColumn) feature.getFeature();
            indexProjection[i++] = column.getOrdinal();
        }
        generator.setOutputProj(
            FennelRelUtil.createTupleProjection(
                repos,
                computeProjectedColumns(indexProjection)));

        //
        // Setup index creation flag
        //
        generator.setCreateIndex(createIndex);

        //
        // Setup dynamic param id
        //
        generator.setInsertRowCountParamId(insertRowCountParamId);

        //
        // Setup Btree accessor parameters
        //
        defineIndexAccessor(generator, rel, index, false, true, false, 0);

        //
        // Set up FemExecutionStreamDef
        //        - setOutputDesc (same as tupleDesc)
        //
        generator.setOutputDesc(
            createUnclusteredBTreeTupleDesc(index));

        //
        // This to keeps the repository validator happy
        //
        Integer [] clusterResidualColumns = new Integer[] {};
        generator.setResidualFilterColumns(
            FennelRelUtil.createTupleProjection(repos, clusterResidualColumns));

        return generator;
    }

    /**
     * Creates a sort streamDef for sorting bitmap entries.
     *
     * @param index index corresponding to the bitmap entries that will be
     * sorted
     * @param estimatedNumRows estimated number of input rows into the sort
     * @param ridOnly true if this sort will only be used to sort single rid
     * values
     * @param earlyClose if true, setup the sorter to do an early close on its
     * producers; in that case, the sorter will explicitly close its producers
     * once it has read all its input; this is needed in the case where the
     * producers of the sort reference a table that's modified by the consumers
     * of the sort
     *
     * @return the created sort streamDef
     */
    FemSortingStreamDef newSorter(
        FemLocalIndex index,
        Double estimatedNumRows,
        boolean ridOnly,
        boolean earlyClose)
    {
        FemSortingStreamDef sortingStream = repos.newFemSortingStreamDef();

        //
        // Bitmap entry keys should be unique, but we save the effort
        // of enforcing uniqueness
        //
        sortingStream.setDistinctness(DistinctnessEnum.DUP_ALLOW);
        sortingStream.setKeyProj(createUnclusteredBTreeKeyProj(index));
        if (!ridOnly) {
            sortingStream.setOutputDesc(createUnclusteredBTreeTupleDesc(index));
        }

        // estimated number of rows in the sort input; if unknown, set to -1
        if (estimatedNumRows == null) {
            sortingStream.setEstimatedNumRows(-1);
        } else {
            sortingStream.setEstimatedNumRows(estimatedNumRows.longValue());
        }
        sortingStream.setEarlyClose(earlyClose);

        return sortingStream;
    }

    FemLbmSplicerStreamDef newSplicer(
        FennelRel rel,
        FemLocalIndex index,
        FemLocalIndex deletionIndex,
        int insertRowCountParamId,
        int writeRowCountParamId,
        boolean createNewIndex)
    {
        FemLbmSplicerStreamDef splicer = repos.newFemLbmSplicerStreamDef();

        // Setup the index that splicer will be writing to
        FemSplicerIndexAccessorDef indexAccessor =
            repos.newFemSplicerIndexAccessorDef();
        defineIndexAccessor(
            indexAccessor,
            rel,
            index,
            false,
            true,
            false,
            0);
        splicer.getIndexAccessor().add(indexAccessor);

        // Setup the deletion index if the splicer will be reading from it.
        // This deletion index scan needs to read data inserted upstream, so
        // it needs to be able to see uncommitted data.
        if (deletionIndex != null) {
            indexAccessor = repos.newFemSplicerIndexAccessorDef();
            defineIndexAccessor(
                indexAccessor,
                rel,
                deletionIndex,
                false,
                false,
                false,
                0);
            splicer.getIndexAccessor().add(indexAccessor);
        }

        //
        // The splicer is the terminal stream of a bitmap stream set.
        // It's output type is the same as the rel's: the standard
        // Dml output type.
        //
        splicer.setInsertRowCountParamId(insertRowCountParamId);
        splicer.setWriteRowCountParamId(writeRowCountParamId);
        splicer.setCreateNewIndex(createNewIndex);

        // NOTE zfong 11/30/06 - Splicer may also write out rid values.
        // As it turns out, the type of a rid is currently the same as a
        // rowcount.
        RelDataType rowType =
            typeFactory.createStructType(
                new RelDataType[] {
                    typeFactory.createSqlType(SqlTypeName.BIGINT)
                },
                new String[] { "ROWCOUNT" });
        splicer.setOutputDesc(
            FennelRelUtil.createTupleDescriptorFromRowType(
                repos,
                typeFactory,
                rowType));

        return splicer;
    }

    FemIndexScanDef newIndexScan(
        FennelRel rel,
        FemLocalIndex index,
        Integer [] projectedColumns)
    {
        FemIndexScanDef scanStream = repos.newFemIndexScanDef();
        defineIndexScan(scanStream, rel, index, projectedColumns);

        return scanStream;
    }

    FemLbmSearchStreamDef newIndexSearch(
        FennelRel rel,
        FemLocalIndex index,
        boolean isUniqueKey,
        boolean isOuter,
        Integer [] inputKeyProj,
        Integer [] inputJoinProj,
        Integer [] inputDirectiveProj,
        Integer [] outputProj,
        FennelDynamicParamId startRidParamId,
        FennelDynamicParamId rowLimitParamId)
    {
        FemLbmSearchStreamDef searchStream = repos.newFemLbmSearchStreamDef();
        defineIndexScan(searchStream, rel, index, outputProj);

        searchStream.setStartRidParamId(startRidParamId.intValue());
        searchStream.setRowLimitParamId(rowLimitParamId.intValue());

        searchStream.setUniqueKey(isUniqueKey);
        searchStream.setOuterJoin(isOuter);
        searchStream.setPrefetch(false);

        if (inputKeyProj != null) {
            searchStream.setInputKeyProj(
                FennelRelUtil.createTupleProjection(repos, inputKeyProj));
        }

        if (inputJoinProj != null) {
            searchStream.setInputJoinProj(
                FennelRelUtil.createTupleProjection(repos, inputJoinProj));
        }

        if (inputDirectiveProj != null) {
            searchStream.setInputDirectiveProj(
                FennelRelUtil.createTupleProjection(repos, inputDirectiveProj));
        }

        return searchStream;
    }

    private void defineIndexScan(
        FemIndexScanDef scanStream,
        FennelRel rel,
        FemLocalIndex index,
        Integer [] outputProj)
    {
        defineIndexStream(scanStream, rel, index, false, false, 0);

        // set FemIndexScanDef
        if (outputProj == null) {
            // If projected fields are not specified, output projection
            // maps to [RID, bitmapfield1, bitmapfield2].
            scanStream.setOutputProj(
                createUnclusteredBTreeBitmapProj(index));
        } else {
            scanStream.setOutputProj(
                FennelRelUtil.createTupleProjection(
                    repos,
                    outputProj));
        }
    }

    private void defineIndexStream(
        FemIndexStreamDef indexStream,
        FennelRel rel,
        FemLocalIndex index,
        boolean clustered,
        boolean write,
        int rootPageIdParamId)
    {
        //
        // Set up FemExecutionStreamDef
        //        - setOutputDesc
        //
        indexStream.setOutputDesc(
            FennelRelUtil.createTupleDescriptorFromRowType(
                repos,
                typeFactory,
                rel.getRowType()));

        defineIndexAccessor(
            indexStream,
            rel,
            index,
            clustered,
            write,
            !write,
            rootPageIdParamId);
    }

    private void defineIndexAccessor(
        FemIndexAccessorDef indexAccessor,
        FennelRel rel,
        FemLocalIndex index,
        boolean clustered,
        boolean write,
        boolean readOnlyCommittedData,
        int rootPageIdParamId)
    {
        final FarragoPreparingStmt stmt = FennelRelUtil.getPreparingStmt(rel);

        //
        // Set up FemIndexAccessorDef
        //        - setRootPageId
        //        - setSegmentId
        //        - setTupleDesc
        //        - setKeyProj
        //
        indexAccessor.setRootPageId(
            stmt.getIndexMap().getIndexRoot(index, write));
        indexAccessor.setRootPageIdParamId(rootPageIdParamId);

        indexAccessor.setSegmentId(
            LcsDataServer.getIndexSegmentId(index));

        long indexId = JmiObjUtil.getObjectId(index);

        if (!write) {
            failIfIndexInvalid(index);
        }

        indexAccessor.setIndexId(indexId);

        FemTupleDescriptor indexTupleDesc;
        if (clustered) {
            indexTupleDesc = createClusteredBTreeTupleDesc();
        } else {
            indexTupleDesc = createUnclusteredBTreeTupleDesc(index);
        }
        indexAccessor.setTupleDesc(indexTupleDesc);

        FemTupleProjection femProj;
        if (clustered) {
            //
            //The key is simply the RID from the [RID, PageId] mapping stored in
            //this index.
            Integer [] keyProj = { 0 };
            femProj = FennelRelUtil.createTupleProjection(repos, keyProj);
        } else {
            femProj = createUnclusteredBTreeKeyProj(index);
        }
        indexAccessor.setKeyProj(femProj);
        indexAccessor.setReadOnlyCommittedData(readOnlyCommittedData);
    }

    /**
     * Fills in a stream definition for this scan.
     *
     * @param scanStream stream definition to fill in
     * @param rel the RelNode containing the cluster
     * @param write whether the cluster will be written
     */
    private void defineScanStream(
        FemLcsRowScanStreamDef scanStream,
        FennelRel rel,
        boolean write)
    {
        // setup each cluster scan def
        for (FemLocalIndex index : clusteredIndexes) {
            FemLcsClusterScanDef clusterScan = repos.newFemLcsClusterScanDef();
            Integer rootPageIdParamId =
                clusterToRootPageIdParamIdMap.get(index);
            defineClusterScan(
                index,
                rel,
                clusterScan,
                write,
                (rootPageIdParamId == null) ? 0 : rootPageIdParamId.intValue());
            scanStream.getClusterScan().add(clusterScan);
        }
    }

    private void failIfIndexInvalid(FemLocalIndex index)
    {
        // REVIEW jvs 10-Dec-2008:  The validator should prevent
        // us from ever actually hitting this, so perhaps it
        // should change to an assertion instead.
        if (index.isInvalid()) {
            throw FarragoResource.instance().QueryAccessNewColumn.ex(
                repos.getLocalizedObjectName(index));
        }
    }

    /**
     * Fills in a cluster scan def for this scan
     *
     * @param index clustered index corresponding to this can
     * @param rel the RelNode containing the cluster
     * @param clusterScan clustered scan to fill in
     * @param write true if the cluster will be written as well as read
     * @param rootPageIdParamId if > 0, the dynamic parameter that will supply
     * the value of the root pageId of the cluster
     */
    private void defineClusterScan(
        FemLocalIndex index,
        FennelRel rel,
        FemLcsClusterScanDef clusterScan,
        boolean write,
        int rootPageIdParamId)
    {
        final FarragoPreparingStmt stmt = FennelRelUtil.getPreparingStmt(rel);

        // setup cluster tuple descriptor and add to cluster map
        FemTupleDescriptor clusterDesc = getClusterTupleDesc(index);
        clusterScan.setClusterTupleDesc(clusterDesc);

        // setup index accessor def fields

        if (!write) {
            failIfIndexInvalid(index);
        }

        if (!FarragoCatalogUtil.isIndexTemporary(index)) {
            clusterScan.setRootPageId(
                stmt.getIndexMap().getIndexRoot(index, write));

            // If we're writing to the cluster, then we want to be able
            // to read that data.
            clusterScan.setReadOnlyCommittedData(!write);
        } else {
            // For a temporary index, each execution needs to bind to
            // a session-private root.  So don't burn anything into
            // the plan.
            clusterScan.setRootPageId(-1);
            clusterScan.setReadOnlyCommittedData(false);
        }
        clusterScan.setRootPageIdParamId(rootPageIdParamId);

        clusterScan.setSegmentId(LcsDataServer.getIndexSegmentId(index));
        clusterScan.setIndexId(JmiObjUtil.getObjectId(index));

        clusterScan.setTupleDesc(
            createClusteredBTreeTupleDesc());

        clusterScan.setKeyProj(
            createClusteredBTreeRidDesc());
    }

    /**
     * Creates input values for a bitmap index generator
     *
     *
The inputs are two columns: [rowCount startRid]
     */
    RexNode [] getUnclusteredInputs(RexBuilder builder)
    {
        // First obtain the row count and starting row id
        //
        // TODO: Make this work for the incremental case
        BigDecimal rowCount = BigDecimal.ZERO;
        BigDecimal startRid = BigDecimal.ZERO;

        // TODO: These types must match the fennel types for
        // RecordNum and LcsRowId
        RelDataType rowCountType =
            typeFactory.createSqlType(SqlTypeName.BIGINT);
        RelDataType ridType = rowCountType;

        return new RexNode[] {
                builder.makeExactLiteral(rowCount, rowCountType),
                builder.makeExactLiteral(startRid, ridType)
            };
    }

    RelDataType getUnclusteredInputType()
    {
        // TODO: These types must match the fennel types for
        // RecordNum and LcsRowId
        RelDataType rowCountType =
            typeFactory.createSqlType(SqlTypeName.BIGINT);
        RelDataType ridType = rowCountType;

        return typeFactory.createStructType(
            new RelDataType[] { rowCountType, ridType },
            new String[] { "ROWCOUNT", "SRID" });
    }

    FemTupleDescriptor getUnclusteredInputDesc()
    {
        return FennelRelUtil.createTupleDescriptorFromRowType(
            repos,
            typeFactory,
            getUnclusteredInputType());
    }

    // ~ Methods for unclustered(bitmap) index ------------------------

    /**
     * Creates a bitmap data row type, [SRID, SegmentDir, Segments]
     */
    public RelDataType createUnclusteredBitmapRowType()
    {
        RelDataType ridType = typeFactory.createSqlType(SqlTypeName.BIGINT);
        RelDataType bitmapType =
            typeFactory.createSqlType(
                SqlTypeName.VARBINARY,
                LbmBitmapSegMaxSize);

        RelDataType segDescType =
            typeFactory.createTypeWithNullability(bitmapType, true);

        RelDataType segType =
            typeFactory.createTypeWithNullability(bitmapType, true);

        return typeFactory.createStructType(
            new RelDataType[] { ridType, segDescType, segType },
            new String[] { "SRID", "SegmentDesc", "Segment" });
    }

    /**
     * Creates a tuple descriptor for bitmap data
     */
    public FemTupleDescriptor createUnclusteredBitmapTupleDesc()
    {
        return FennelRelUtil.createTupleDescriptorFromRowType(
            repos,
            typeFactory,
            createUnclusteredBitmapRowType());
    }

    /**
     * Creates a key projection for bitmap data. The only key column is the
     * first column, SRID
     */
    public FemTupleProjection createUnclusteredBitmapKeyProj()
    {
        return FennelRelUtil.createTupleProjection(
            repos,
            FennelRelUtil.newIotaProjection(1));
    }

    FemSortingStreamDef newBitmapSorter()
    {
        FemSortingStreamDef sortingStream = repos.newFemSortingStreamDef();
        sortingStream.setDistinctness(DistinctnessEnum.DUP_ALLOW);
        sortingStream.setKeyProj(createUnclusteredBitmapKeyProj());
        sortingStream.setOutputDesc(createUnclusteredBitmapTupleDesc());
        sortingStream.setEarlyClose(false);

        // TODO zfong 8/16/06 - replace this with real stats when we can
        // call RelMetadataQuery.getRowCount on physical RelNodes
        sortingStream.setEstimatedNumRows(-1);
        return sortingStream;
    }

    private void setBitmapStreamParams(
        FemLbmBitOpStreamDef bitOpStream,
        FennelDynamicParamId startRidParamId,
        FennelDynamicParamId rowLimitParamId)
    {
        bitOpStream.setStartRidParamId(startRidParamId.intValue());
        bitOpStream.setRowLimitParamId(rowLimitParamId.intValue());

        bitOpStream.setOutputDesc(createUnclusteredBitmapTupleDesc());
    }

    FemLbmIntersectStreamDef newBitmapIntersect(
        FennelDynamicParamId startRidParamId,
        FennelDynamicParamId rowLimitParamId)
    {
        FemLbmIntersectStreamDef intersectStream =
            repos.newFemLbmIntersectStreamDef();

        setBitmapStreamParams(
            intersectStream,
            startRidParamId,
            rowLimitParamId);

        return intersectStream;
    }

    FemLbmMinusStreamDef newBitmapMinus(
        FennelDynamicParamId startRidParamId,
        FennelDynamicParamId rowLimitParamId,
        RelNode child)
    {
        FemLbmMinusStreamDef minusStream = repos.newFemLbmMinusStreamDef();

        setBitmapStreamParams(
            minusStream,
            startRidParamId,
            rowLimitParamId);

        // override the default output tuple
        minusStream.setOutputDesc(
            FennelRelUtil.createTupleDescriptorFromRowType(
                repos,
                typeFactory,
                child.getRowType()));

        return minusStream;
    }

    LcsIndexMinusRel createMinusOfDeletionIndex(
        FennelRel rel,
        LcsTable lcsTable,
        RelNode input)
    {
        FennelRelImplementor implementor = FennelRelUtil.getRelImplementor(rel);
        FennelRelParamId startRidParamId = implementor.allocateRelParamId();
        FennelRelParamId rowLimitParamId = implementor.allocateRelParamId();
        LcsIndexSearchRel delIndexScan =
            createDeletionIndexScan(
                rel,
                lcsTable,
                startRidParamId,
                rowLimitParamId,
                false);
        RelNode [] minusInputs = new RelNode[2];
        minusInputs[0] = input;
        minusInputs[1] = delIndexScan;
        LcsIndexMinusRel minus =
            new LcsIndexMinusRel(
                rel.getCluster(),
                minusInputs,
                lcsTable,
                startRidParamId,
                rowLimitParamId);
        return minus;
    }

    /**
     * Creates an index search on the deletion index corresponding to an lcs
     * table. A deletion index is searched by RID.
     *
     * @param rel the rel from which this scan is being generated
     * @param lcsTable the table whose deletion index is to be scanned
     * @param startRidParamId start rid parameter for the index search
     * @param rowLimitParamId row limit parameter for the index search
     * @param fullScan true if deletion index will be used with a full table
     * scan
     *
     * @return the created index search
     */
    LcsIndexSearchRel createDeletionIndexScan(
        FennelRel rel,
        LcsTable lcsTable,
        FennelRelParamId startRidParamId,
        FennelRelParamId rowLimitParamId,
        boolean fullScan)
    {
        FemLocalIndex delIndex =
            FarragoCatalogUtil.getDeletionIndex(
                repos,
                lcsTable.getCwmColumnSet());

        RelNode keyInput = createDelIndexScanInput(rel, fullScan);

        Integer [] inputDirectiveProj = { 0, 2 };
        Integer [] inputKeyProj = { 1, 3 };

        LcsIndexSearchRel indexSearch =
            new LcsIndexSearchRel(
                rel.getCluster(),
                keyInput,
                lcsTable,
                delIndex,
                false,
                null,
                true,
                false,
                false,
                inputKeyProj,
                null,
                inputDirectiveProj,
                startRidParamId,
                rowLimitParamId,
                null);

        return indexSearch;
    }

    /**
     * Creates the RelNode that corresponds to the key input into the deletion
     * index scan. The type of input depends on whether or not a full scan is
     * being done on the deletion index.
     *
     * @param rel the original rel from which this rel is being generated
     * @param fullScan true if a full scan will be done on the deletion index
     *
     * @return the created RelNode
     */
    private RelNode createDelIndexScanInput(FennelRel rel, boolean fullScan)
    {
        // Search on the index using the rid as the key
        FarragoPreparingStmt stmt = FennelRelUtil.getPreparingStmt(rel);
        FarragoTypeFactory typeFactory = stmt.getFarragoTypeFactory();
        RelDataType directiveType =
            typeFactory.createSqlType(
                SqlTypeName.CHAR,
                1);
        RelDataType keyType =
            typeFactory.createTypeWithNullability(
                typeFactory.createSqlType(SqlTypeName.BIGINT),
                true);

        // Setup the directives.  In the case of a full scan, setup an
        // unbounded lower and upper search.  In the index scan case, setup
        // a >= search on the rid key.
        RelDataType keyRowType =
            typeFactory.createStructType(
                new RelDataType[] {
                    directiveType,
                    keyType,
                    directiveType,
                    keyType
                },
                new String[] {
                    "lowerBoundDirective",
                    "lowerBoundKey",
                    "upperBoundDirective",
                    "upperBoundKey"
                });

        List<List<RexLiteral>> inputTuples = new ArrayList<List<RexLiteral>>();
        List<RexLiteral> tuple = new ArrayList<RexLiteral>();
        RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
        SargFactory sargFactory = new SargFactory(rexBuilder);

        SargMutableEndpoint lowerEndpoint = sargFactory.newEndpoint(keyType);
        if (fullScan) {
            lowerEndpoint.setInfinity(-1);
        } else {
            // for now, just set the actual search key value to null; this
            // will get filled in at runtime with the value of the startRid
            // dynamic parameter
            lowerEndpoint.setFinite(
                SargBoundType.LOWER,
                SargStrictness.CLOSED,
                rexBuilder.constantNull());
        }
        RexLiteral lowerBoundDirective =
            FennelRelUtil.convertEndpoint(rexBuilder, lowerEndpoint);

        SargMutableEndpoint upperEndpoint = sargFactory.newEndpoint(keyType);
        upperEndpoint.setInfinity(1);

        RexLiteral upperBoundDirective =
            FennelRelUtil.convertEndpoint(rexBuilder, upperEndpoint);

        tuple.add(lowerBoundDirective);
        tuple.add(rexBuilder.constantNull());
        tuple.add(upperBoundDirective);
        tuple.add(rexBuilder.constantNull());
        inputTuples.add(tuple);

        RelNode keyRel =
            new FennelValuesRel(
                rel.getCluster(),
                keyRowType,
                inputTuples,
                false);

        RelNode keyInput =
            RelOptRule.mergeTraitsAndConvert(
                rel.getTraits(),
                FennelRel.FENNEL_EXEC_CONVENTION,
                keyRel);
        assert (keyInput != null);

        return keyInput;
    }

    private FemAbstractColumn getIndexColumn(
        FemLocalIndex index,
        int position)
    {
        List<CwmIndexedFeature> indexedFeatures = index.getIndexedFeature();

        if ((position < 0) || (position >= indexedFeatures.size())) {
            return null;
        }

        CwmIndexedFeature indexedFeature = indexedFeatures.get(position);

        return (FemAbstractColumn) indexedFeature.getFeature();
    }

    /**
     * Determines the best index to be used to process a semijoin
     *
     * @param semiJoinKeys keys of the semijoin that we are trying to find an
     * index for.
     * @param bestKeyList appends the list of specific keys within the input
     * parameter that match an index if an appropriate index is available
     *
     * @return best index, if available; else null is returned
     */
    public FemLocalIndex findSemiJoinIndex(
        List<Integer> semiJoinKeys,
        List<Integer> bestKeyList)
    {
        // loop through the indexes and either find the one that has the
        // longest matching keys, or the first one that matches all the
        // semijoin keys
        Integer [] bestKeyOrder = {};
        FemLocalIndex bestIndex = null;
        int maxNkeys = 0;
        for (
            FemLocalIndex index
            : FarragoCatalogUtil.getUnclusteredIndexes(repos, table))
        {
            Integer [] keyOrder = new Integer[semiJoinKeys.size()];
            int nKeys = matchIndexKeys(index, semiJoinKeys, keyOrder);
            if (nKeys > maxNkeys) {
                maxNkeys = nKeys;
                bestKeyOrder = keyOrder;
                bestIndex = index;
                if (maxNkeys == semiJoinKeys.size()) {
                    break;
                }
            }
        }
        for (int i = 0; i < maxNkeys; i++) {
            bestKeyList.add(bestKeyOrder[i]);
        }

        return bestIndex;
    }

    /**
     * Determines if an index matches a set of keys representing RexInputRefs
     *
     * @param index index being matched against
     * @param keys keys representing the inputRefs that need to be matched
     * against the index
     * @param keyOrder returns the positions of the matching RexInputRefs in the
     * order in which they match the index
     *
     * @return number of matching keys
     */
    public int matchIndexKeys(
        FemLocalIndex index,
        List<Integer> keys,
        Integer [] keyOrder)
    {
        int nMatches = 0;

        for (int i = 0; i < index.getIndexedFeature().size(); i++) {
            keyOrder[i] = -1;
            FemAbstractColumn idxCol = getIndexColumn(index, i);
            final List<FemAbstractColumn> columns =
                Util.cast(table.getFeature(), FemAbstractColumn.class);
            for (int j = 0; j < keys.size(); j++) {
                FemAbstractColumn keyCol = columns.get(keys.get(j));
                if (idxCol.equals(keyCol)) {
                    keyOrder[i] = j;
                    nMatches++;
                    break;
                }
            }

            // if no match was found for the index key or we've matched
            // every RexInputRef, stop searching
            if ((keyOrder[i] == -1) || (nMatches == keys.size())) {
                break;
            }
        }
        return nMatches;
    }

    /**
     * Retrieves a list of clusters corresponding to clusters containing
     * residual filtered columns.  The list of clusters is returned in the same
     * order as the residual filtered columns.  Note that the number of
     * clusters may be smaller than the number of residual columns, if a
     * cluster has more than one column.
     *
     * @param residualColumns array of flattened ordinals corresponding to the
     * columns that have residual filters
     *
     * @return the list of residual column clusters
     */
    public List<FemLocalIndex> createResidualClusterList(
        Integer[] residualColumns)
    {
        List<FemLocalIndex> residualClusterList =
            new ArrayList<FemLocalIndex>();

        // Add the clusters corresponding to residual columns
        for (int i = 0; i < residualColumns.length; i++) {
            FemLocalIndex cluster = ordinalToClusterMap.get(residualColumns[i]);
            if (!residualClusterList.contains(cluster)) {
                residualClusterList.add(cluster);
            }
        }

        return residualClusterList;
    }
}

// End LcsIndexGuide.java


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">

<TITLE>
Spring Framework: Uses of Interface com.interface21.transaction.interceptor.TransactionAttribute
</TITLE>
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

Uses of Interface
com.interface21.transaction.interceptor.TransactionAttribute

Packages that use TransactionAttribute

com.interface21.transaction.interceptor
AOP-based solution for declarative transaction demarcation.

Uses of TransactionAttribute in com.interface21.transaction.interceptor

Classes in com.interface21.transaction.interceptor that implement TransactionAttribute

 class
DefaultTransactionAttribute

          Transaction attribute that takes EJB approach to rolling
 back on runtime, but not checked, exceptions.

 class
RuleBasedTransactionAttribute

          TransactionAttribute implementation that works out whether a
 given exception should cause transaction rollback by applying
 a number of rollback rules, both positive and negative.

Methods in com.interface21.transaction.interceptor that return TransactionAttribute

 TransactionAttribute
MapTransactionAttributeSource.getTransactionAttribute(org.aopalliance.intercept.MethodInvocation invocation)

 TransactionAttribute
AttributeRegistryTransactionAttributeSource.getTransactionAttribute(org.aopalliance.intercept.MethodInvocation mi)

protected  TransactionAttribute
AttributeRegistryTransactionAttributeSource.findTransactionAttribute(org.aopalliance.intercept.MethodInvocation invocation)

          Return the transaction attribute for this invocation.

 TransactionAttribute
TransactionAttributeSource.getTransactionAttribute(org.aopalliance.intercept.MethodInvocation invocation)

          Return the transaction attribute for this method.

Methods in com.interface21.transaction.interceptor with parameters of type TransactionAttribute

 void
MapTransactionAttributeSource.addTransactionalMethod(java.lang.reflect.Method method,
                       TransactionAttribute attr)

          Add an attribute for a transactional method.

 void
MapTransactionAttributeSource.addTransactionalMethod(java.lang.String name,
                       TransactionAttribute attr)

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

Rod Johnson and Spring contributors 2001-2003.


text:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.echessa.noteapp.EditNoteActivity" >

    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never"/>

</menu>
<!-- From: file:/Users/Trace_route/AndroidStudioProjects/Android-Parse/app/src/main/res/menu/edit_note.xml -->