eigenbase-farrago-0.9.0/0000755000175000017500000000000011173714170014757 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/intellij/0000755000175000017500000000000011173714170016571 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/intellij/farrago.iml0000444000175000017500000000403211173714170020712 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/intellij/farragoCatalog.iml0000444000175000017500000000116411173714170022210 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/testgen/0000755000175000017500000000000011173714170016430 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/testgen/generateSqlTestWrapper.xsl0000444000175000017500000000310611173714170023631 0ustar drazzibdrazzib // This class generated by ant target generateSqlTestWrapper package ; /** * Wraps .sql file diff-based tests with JUnit test methods for * convenient execution from within your favorite JUnit-aware IDE. */ public class extends { public (String testName) throws Exception { super(testName); } protected void setUp() throws Exception { // run cleanup before each test case runCleanup(); super.setUp(); addDiffMask("\\$Id.*\\$"); setVerbose(true); } } // End .java public void test_() throws Exception { runSqlLineTest(""); } } eigenbase-farrago-0.9.0/testgen/README0000444000175000017500000000004011173714170017300 0ustar drazzibdrazzibTest data gets generated here. eigenbase-farrago-0.9.0/testgen/FarragoSorterTest/0000755000175000017500000000000011173714170022050 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/testgen/FarragoSorterTest/setup.sql0000444000175000017500000000117311173714170023731 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/testgen/FarragoSorterTest/setup.sql#1 $ -- Setup SQL/MED data access to CSV files generated in this directory -- create a private wrapper for jdbc (don't use the standard jdbc wrapper) create foreign data wrapper test_jdbc library 'plugin/FarragoMedJdbc.jar' language java; -- create a server for this directory create server csv_server foreign data wrapper test_jdbc options( driver_class 'org.relique.jdbc.csv.CsvDriver', url 'jdbc:relique:csv:testgen/FarragoSorterTest/data', schema_name 'TESTDATA'); -- create the schema which will hold foreign table definitions create schema sortertest; eigenbase-farrago-0.9.0/testgen/FarragoSorterTest/setup.ref0000444000175000017500000000125211173714170023704 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/testgen/FarragoSorterTest/setup.ref#5 $ > -- Setup SQL/MED data access to CSV files generated in this directory > > -- create a private wrapper for jdbc (don't use the standard jdbc wrapper) > create foreign data wrapper test_jdbc > library 'plugin/FarragoMedJdbc.jar' > language java; > > -- create a server for this directory > create server csv_server > foreign data wrapper test_jdbc > options( > driver_class 'org.relique.jdbc.csv.CsvDriver', > url 'jdbc:relique:csv:testgen/FarragoSorterTest/data', > schema_name 'TESTDATA'); > > -- create the schema which will hold foreign table definitions > create schema sortertest; > > !quit eigenbase-farrago-0.9.0/catalog/0000755000175000017500000000000011173714170016371 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/catalog/xmi/0000755000175000017500000000000011173714170017166 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/catalog/xmi/resolveCwmRefs.xsl0000444000175000017500000000725011173714170022666 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/xmi/FarragoConfTemplate.xmi0000444000175000017500000000322011173714170023563 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/xmi/deleteUmlDiagrams.xsl0000444000175000017500000000201111173714170023276 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/xmi/extractArgoModel.xsl0000444000175000017500000000134311173714170023161 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/xmi/extractArgoTimestamp.xsl0000444000175000017500000000123111173714170024060 0ustar drazzibdrazzib fem.timestamp= eigenbase-farrago-0.9.0/catalog/xmi/transformCWM.xsl0000444000175000017500000001463311173714170022305 0ustar drazzibdrazzib net.sf net.sf 132 unlimited true defaultValue public_vis eigenbase-farrago-0.9.0/catalog/xmi/transformFEME.xsl0000444000175000017500000000414311173714170022366 0ustar drazzibdrazzib PrimitiveTypesRef PrimitiveTypesRef eigenbase-farrago-0.9.0/catalog/xmi/transformFEM.xsl0000444000175000017500000000320211173714170022254 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/xmi/FarragoExtMetamodel.uml0000444000175000017500000645553011173714170023617 0ustar drazzibdrazzib The Eigenbase Project info@eigenbase.org 0.24 Farrago Extension Metamodel UML 1.4 true false true true true true true true 1 ArgoUML (using Netbeans XMI Writer version 1.0) 0.24(5) revised on $Date: 2006-11-06 19:55:22 +0100 (Mon, 06 Nov 2006) $ <p> </p> Package Attribute DataType Class Class Class Dependency Dependency Dependency Class Class Dependency <p> FEM is the Farrago Extensions Model. It contains Farrago-specific submodels not covered by the standard CWM. </p> FEM <p> The Fennel model defines classes used for metadata communication with Fennel via JNI+XML. </p> FEMFennel true <p>Projects attributes of leaf BTree tuples to be interpreted as a PageIds bearing additional data associated with the tree (meaning it should be dropped along with the tree). Ignored if unset (the default).</p> <p>Execution object which calculates expressions over a set of windows. An output record is made up expressions drawn from the input record and the current bucket of each window.</p> <p>Note that this a window stream has a superset of the functionality of the {@link FemCalcTupleStreamDef} execution object.</p> <p>If true, the output program sets a status register which determines whether to output the row.</p> <p>Calculator program to generate a row of output.</p> <p>Input fields to the programs are the fields of the input record, followed by the fields of the current bucket of each window.</p> <p>If 'filter' is true, the program sets a status register which the XO should use to determine whether to output the row.</p> <p>List of columns on which the input stream is sorted.</p> <p>The definition of a window inside a {@link FemWindowStreamDef}.</p> <p>A window has either a logical or physical range, and contains a number of partitions:</p> <ul type="disc"> <li>A logical window is defined by a range of values, and may have several partitions.</li> <li>A physical window is defined by a range of rows, and may have several partitions. </li> </ul> <p>List of columns to sort the window on. For example, in <span style="font-family:Courier">WINDOW w AS (ORDER BY hiredate PARTITION BY gender ROWS 5 PRECEDING)</span>, the order list is &quot;hiredate&quot;.</p> <p>Often the optimizer will have ensured that the input stream is already sorted on the sort key, or at least a subset of it; for infinite relations, this is required in order to perform aggregation. See {@link FemWindowStreamDef#getInputOrderKeyList}.</p> <p>True if the window is physical (defined by a number of rows); false if the window is logical (defined by a range of values).</p> <p>If physical, the number of rows; if logical, the value range (for example, 3,600,000 milliseconds).</p> <p>This is the offset of the window. Positive value refers to a leading window and negative value refers to a trailing window.</p> <p>A set of rows within a window which have a common value for a partitioning key. Each row is referred to as a 'bucket'.</p> <p>There are actions -- expressed as calculator programs -- which get executed when a new bucket is created, when a set of values are added to a bucket, and when a set of values are removed from a bucket.</p> <p>List of columns to partition the window on.</p> <p>Calculator program executed to initialize a bucket of this window. Typically simply zeroes out the values.</p> <p>Calculator program executed to add a value to each field of a bucket of this window.</p> <p>Calculator program executed to remove a value from each field of a bucket of this window.</p> <p>Describes the types of the columns in a bucket belonging to this window.</p> <p>Definition for a stream which combines tuples from two or more input streams.</p> <p>Whether to read all rows from a given input before reading the first row from the next input.</p> <p>Execution object with zero or more inputs and zero or more outputs and a java class in the middle.</p> <p>The fully-qualified name of the transform class.</p> <p>Reserved for future use. We may use it to hold the mode in which the class is invoked: using cooperative or pre-emptive scheduling.</p> <p>Handle of the java object.</p> <p>Dummy definition of an execution object, generated by planner tests but never converted into a real execution object.</p> <p>Describes the type of operator being implemented.</p> <p>Contains the properties of this mock execution stream, generally (but not necessarily) as an XML string.</p> false <p> The Config model defines configuration information for Farrago. </p> FEMConfig <p>FarragoConfig defines top-level configuration parameters for Farrago.&nbsp; Each attribute corresponds to an individual parameter.&nbsp; TODO:&nbsp; fill in documentation for all parameters.</p> <p>Represents the name of this configuration.&nbsp; Multiple named configurations will be possible one day.</p> <p>Controls whether all access to Fennel storage should be disabled. </p> <p>Whether the user catalog has been enabled yet for this database.</p> unlimited unlimited true <p>Represents a grant given to the creator of a given object. </p> <p>A user must be assigned with a namespace, it can be a catolog or a schema within a given catalog. </p> <p>A user can only have one default namespace, if the namespace is a schema then the user </p> <p>The assignee of the namespace, this namespace is set to be the session's catalog or schema when this user logs on</p> true true unlimited unlimited 32768 unlimited unlimited <p>The original SQL text of this view.</p> <p>The SQL standard says that the objects referenced by a view are fixed when the view is created. For example, if a column is added to a table referenced via 'select *', the view will not acquire an extra column. If the original definition contains '*'s and non fully-qualified object references, it may become inconsistent with the actual definition.</p> unlimited unlimited A SampleDataset is a named association of a ColumnSet of sample data with an AbstractColumnSet.&nbsp; An AbstractColumnSet can have several SampleDatasets, but their names must be distinct. If a query which uses (directly, or indirectly via a view) the AbstractColumnSet requests to use a named sample, and the AbstractColumnSet posesses such as sample, then the query is rewritten to use the sample data set instead. <p>Note that the second 's' in 'SampleDataset' is not capitalized, unlike the 's' in 'ColumnSet'. That is because 'dataset' is an English word.</p> unlimited Association Abstraction net.sf.farrago.catalog true true true true true true true true true true true true true true true true true true true true FEMConfig true true true true Cmd CmdOpenDatabase createDatabase : Boolean params : DatabaseParam resultRecoveryRequired : Boolean sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" DatabaseCmd sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" DatabaseParam name : String value : String CmdBeginTxn readOnly : Boolean CmdCloseDatabase sourcePortFig="Fig7" destPortFig="Fig3" sourceFigNode="Fig7" destFigNode="Fig3" CmdCheckpoint fuzzy : Boolean async : Boolean sourcePortFig="Fig9" destPortFig="Fig3" sourceFigNode="Fig9" destFigNode="Fig3" CmdSetParam param : DatabaseParam sourcePortFig="Fig11" destPortFig="Fig3" sourceFigNode="Fig11" destFigNode="Fig3" TxnCmd sourcePortFig="Fig13" destPortFig="Fig0" sourceFigNode="Fig13" destFigNode="Fig0" TupleStreamGraphCmd sourcePortFig="Fig15" destPortFig="Fig0" sourceFigNode="Fig15" destFigNode="Fig0" CmdAlterSystemDeallocate oldestLabelCsn : Long sourcePortFig="Fig17" destPortFig="Fig3" sourceFigNode="Fig17" destFigNode="Fig3" BeginTxnCmd sourcePortFig="Fig19" destPortFig="Fig3" sourceFigNode="Fig19" destFigNode="Fig3" sourcePortFig="Fig6" destPortFig="Fig19" sourceFigNode="Fig6" destFigNode="Fig19" CmdBeginTxnWithCsn sourcePortFig="Fig22" destPortFig="Fig19" sourceFigNode="Fig22" destFigNode="Fig19" CmdInitiateBackup backupPathname : String checkSpaceRequirements : Boolean spacePadding : Long lowerBoundCsn : Long compressionProgram : String resultDataDeviceSize : Long sourcePortFig="Fig24" destPortFig="Fig3" sourceFigNode="Fig24" destFigNode="Fig3" CsnHandleReturningCmd sourcePortFig="Fig24.0" destPortFig="Fig26.0" sourceFigNode="Fig24" destFigNode="Fig26" CmdCompleteBackup lowerBoundCsn : Long upperBoundCsn : Long sourcePortFig="Fig28" destPortFig="Fig3" sourceFigNode="Fig28" destFigNode="Fig3" CmdRestoreFromBackup backupPathname : String fileSize : Long compressionProgram : String lowerBoundCsn : Long upperBoundCsn : Long sourcePortFig="Fig30" destPortFig="Fig3" sourceFigNode="Fig30" destFigNode="Fig3" CmdAbandonBackup sourcePortFig="Fig32" destPortFig="Fig3" sourceFigNode="Fig32" destFigNode="Fig3" FarragoConfig name : String fennelDisabled : Boolean userCatalogEnabled : Boolean codeCacheMaxBytes : Long checkpointInterval : Integer serverRmiRegistryPort : Integer serverSingleListenerPort : Integer calcVirtualMachine : CalcVirtualMachine javaCompilerClassName : String connectionTimeoutMillis : Long FennelConfig databaseInitSize : Integer databaseIncrementSize : Integer databaseMaxSize : Integer tempInitSize : Integer tempIncrementSize : Integer tempMaxSize : Integer databaseShadowLogInitSize : Integer databaseShadowLogIncrementSize : Integer databaseTxnLogInitSize : Integer databaseTxnLogIncrementSize : Integer cachePagesMax : Integer cachePagesInit : Integer cachePageSize : Integer groupCommitInterval : Integer resourceDir : String jniHandleTraceFile : String expectedConcurrentStatements : Integer cacheReservePercentage : Integer deviceSchedulerType : DeviceSchedulerType freshmenPageQueuePercentage : Integer pageHistoryQueuePercentage : Integer prefetchPagesMax : Integer prefetchThrottleRate : Integer sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" <<enumeration>> CalcVirtualMachine CALCVM_FENNEL : CalcVirtualMachine CALCVM_JAVA : CalcVirtualMachine CALCVM_AUTO : CalcVirtualMachine <<enumeration>> DeviceSchedulerType threadPool : DeviceSchedulerType ioCompletionPort : DeviceSchedulerType aioPolling : DeviceSchedulerType aioSignal : DeviceSchedulerType aioLinux : DeviceSchedulerType default : DeviceSchedulerType IndexCmd tupleDesc : TupleDescriptor keyProj : TupleProjection segmentId : Long indexId : Long leafPageIdProj : TupleProjection CmdCreateIndex sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" CmdDropIndex IndexAccessCmd rootPageId : Long sourcePortFig="Fig4" destPortFig="Fig0" sourceFigNode="Fig4" destFigNode="Fig0" sourcePortFig="Fig3" destPortFig="Fig4" sourceFigNode="Fig3" destFigNode="Fig4" CmdVerifyIndex estimate : Boolean includeTuples : Boolean resultPageCount : Long resultUniqueKeyCount : Long sourcePortFig="Fig7" destPortFig="Fig4" sourceFigNode="Fig7" destFigNode="Fig4" CmdTruncateIndex sourcePortFig="Fig9" destPortFig="Fig3" sourceFigNode="Fig9" destFigNode="Fig3" TxnCmd sourcePortFig="Fig0.0" destPortFig="Fig11.0" sourceFigNode="Fig0" destFigNode="Fig11" Cmd TupleStreamGraphCmd sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" TxnCmd sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" CmdSavepoint sourcePortFig="Fig5" destPortFig="Fig3" sourceFigNode="Fig5" destFigNode="Fig3" EndTxnCmd sourcePortFig="Fig7" destPortFig="Fig3" sourceFigNode="Fig7" destFigNode="Fig3" CmdRollback sourcePortFig="Fig9" destPortFig="Fig7" sourceFigNode="Fig9" destFigNode="Fig7" CmdCommit sourcePortFig="Fig11" destPortFig="Fig7" sourceFigNode="Fig11" destFigNode="Fig7" CmdCreateExecutionStreamGraph sourcePortFig="Fig13" destPortFig="Fig3" sourceFigNode="Fig13" destFigNode="Fig3" CmdPrepareExecutionStreamGraph streamDefs : ExecutionStreamDef degreeOfParallelism : Integer sourcePortFig="Fig15" destPortFig="Fig1" sourceFigNode="Fig15" destFigNode="Fig1" CmdCreateStreamHandle streamName : String input : Boolean sourcePortFig="Fig17" destPortFig="Fig1" sourceFigNode="Fig17" destFigNode="Fig1" IndexCmd sourcePortFig="Fig19" destPortFig="Fig3" sourceFigNode="Fig19" destFigNode="Fig3" CmdVersionIndexRoot oldRootPageId : Long newRootPageId : Long sourcePortFig="Fig21.0" destPortFig="Fig3.0" sourceFigNode="Fig21" destFigNode="Fig3" CsnHandleReturningCmd ExecStreamDataFlow implicit : Boolean ExecutionStreamDef name : String outputDesc : TupleDescriptor sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" TupleStreamDef sourcePortFig="Fig4" destPortFig="Fig1" sourceFigNode="Fig4" destFigNode="Fig1" DynamicParamUse dynamicParamId : Integer read : Boolean sourcePortFig="Fig1.0" destPortFig="Fig6.0" sourceFigNode="Fig1" destFigNode="Fig6" TupleStreamDef KeyAccessorDef keyProj : TupleProjection IndexAccessorDef rootPageId : Long segmentId : Long indexId : Long tupleDesc : TupleDescriptor rootPageIdParamId : Integer readOnlyCommittedData : Boolean sourcePortFig="Fig2" destPortFig="Fig1" sourceFigNode="Fig2" destFigNode="Fig1" SortingStreamDef distinctness : Distinctness estimatedNumRows : Long descendingProj : TupleProjection earlyClose : Boolean sourcePortFig="Fig4" destPortFig="Fig1" sourceFigNode="Fig4" destFigNode="Fig1" sourcePortFig="Fig4" destPortFig="Fig0" sourceFigNode="Fig4" destFigNode="Fig0" IndexStreamDef sourcePortFig="Fig7" destPortFig="Fig0" sourceFigNode="Fig7" destFigNode="Fig0" sourcePortFig="Fig7" destPortFig="Fig2" sourceFigNode="Fig7" destFigNode="Fig2" IndexLoaderDef distinctness : Distinctness monotonic : Boolean sourcePortFig="Fig10" destPortFig="Fig7" sourceFigNode="Fig10" destFigNode="Fig7" IndexScanDef outputProj : TupleProjection sourcePortFig="Fig12" destPortFig="Fig7" sourceFigNode="Fig12" destFigNode="Fig7" IndexSearchDef uniqueKey : Boolean outerJoin : Boolean inputKeyProj : TupleProjection inputJoinProj : TupleProjection inputDirectiveProj : TupleProjection prefetch : Boolean sourcePortFig="Fig14" destPortFig="Fig12" sourceFigNode="Fig14" destFigNode="Fig12" IndexWriterDef inputProj : TupleProjection distinctness : Distinctness updateInPlace : Boolean sourcePortFig="Fig16" destPortFig="Fig2" sourceFigNode="Fig16" destFigNode="Fig2" <<enumeration>> Distinctness DUP_ALLOW : Distinctness DUP_DISCARD : Distinctness DUP_FAIL : Distinctness Correlation id : Integer offset : Integer sourcePortFig="Fig14.0" destPortFig="Fig19.0" sourceFigNode="Fig14" destFigNode="Fig19" IndexWriterDef inputProj : TupleProjection distinctness : Distinctness updateInPlace : Boolean TupleStreamDef TableWriterDef sourcePortFig="Fig2" destPortFig="Fig0" sourceFigNode="Fig2" destFigNode="Fig0" sourcePortFig="Fig2" destPortFig="Fig1" sourceFigNode="Fig2" destFigNode="Fig1" TableInserterDef sourcePortFig="Fig5" destPortFig="Fig2" sourceFigNode="Fig5" destFigNode="Fig2" TableDeleterDef sourcePortFig="Fig7" destPortFig="Fig2" sourceFigNode="Fig7" destFigNode="Fig2" TableUpdaterDef updateProj : TupleProjection sourcePortFig="Fig9" destPortFig="Fig2" sourceFigNode="Fig9" destFigNode="Fig2" TupleStreamDef JavaSinkStreamDef streamId : Integer sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" MockTupleStreamDef rowCount : Long sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" ValuesStreamDef tupleBytesBase64 : String sourcePortFig="Fig5" destPortFig="Fig0" sourceFigNode="Fig5" destFigNode="Fig0" SplitterStreamDef sourcePortFig="Fig7" destPortFig="Fig0" sourceFigNode="Fig7" destFigNode="Fig0" FlatFileTupleStreamDef dataFilePath : String errorFilePath : String hasHeader : Boolean numRowsScan : Integer fieldDelimiter : String rowDelimiter : String quoteCharacter : String escapeCharacter : String calcProgram : String codePage : Integer translationRecovery : Boolean substituteCharacter : String lenient : Boolean trim : Boolean mapped : Boolean sourcePortFig="Fig9" destPortFig="Fig0" sourceFigNode="Fig9" destFigNode="Fig0" ColumnName name : String sourcePortFig="Fig9.0" destPortFig="Fig11.0" sourceFigNode="Fig9" destFigNode="Fig11" <<enumeration>> TableSamplingMode SAMPLING_OFF : TableSamplingMode SAMPLING_BERNOULLI : TableSamplingMode SAMPLING_SYSTEM : TableSamplingMode BernoulliSamplingStreamDef samplingRate : Float repeatable : Boolean repeatableSeed : Integer sourcePortFig="Fig14.0" destPortFig="Fig0.0" sourceFigNode="Fig14" destFigNode="Fig0" BufferingTupleStreamDef inMemory : Boolean multipass : Boolean sourcePortFig="Fig16" destPortFig="Fig0" sourceFigNode="Fig16" destFigNode="Fig0" MultiUseBufferingStreamDef readerRefCountParamId : Integer sourcePortFig="Fig18" destPortFig="Fig16" sourceFigNode="Fig18" destFigNode="Fig16" BufferWriterStreamDef sourcePortFig="Fig20" destPortFig="Fig18" sourceFigNode="Fig20" destFigNode="Fig18" BufferReaderStreamDef sourcePortFig="Fig22" destPortFig="Fig18" sourceFigNode="Fig22" destFigNode="Fig18" TupleStreamDef CorrelationJoinStreamDef correlations : Correlation sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" CartesianProductStreamDef leftOuter : Boolean sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" MergeStreamDef sequential : Boolean prePullInputs : Boolean sourcePortFig="Fig5" destPortFig="Fig0" sourceFigNode="Fig5" destFigNode="Fig0" GenericStreamDef type : String content : String sourcePortFig="Fig7" destPortFig="Fig0" sourceFigNode="Fig7" destFigNode="Fig0" Correlation id : Integer offset : Integer JavaTransformStreamDef javaClassName : String reserved : String streamId : Integer sourcePortFig="Fig10" destPortFig="Fig0" sourceFigNode="Fig10" destFigNode="Fig0" BarrierStreamDef returnMode : BarrierReturnMode sourcePortFig="Fig12" destPortFig="Fig0" sourceFigNode="Fig12" destFigNode="Fig0" LhxJoinStreamDef leftKeyProj : TupleProjection rightKeyProj : TupleProjection numBuildRows : Long cndBuildKeys : Long leftInner : Boolean rightInner : Boolean leftOuter : Boolean rightOuter : Boolean isSetopDistinct : Boolean isSetopAll : Boolean filterNullProj : TupleProjection sourcePortFig="Fig14" destPortFig="Fig0" sourceFigNode="Fig14" destFigNode="Fig0" DynamicParameter parameterId : Integer sourcePortFig="Fig12.0" destPortFig="Fig16.0" sourceFigNode="Fig12" destFigNode="Fig16" <<enumeration>> BarrierReturnMode BARRIER_RET_FIRST_INPUT : BarrierReturnMode BARRIER_RET_ANY_INPUT : BarrierReturnMode BARRIER_RET_ALL_INPUTS : BarrierReturnMode NestedLoopJoinStreamDef sourcePortFig="Fig19" destPortFig="Fig3" sourceFigNode="Fig19" destFigNode="Fig3" sourcePortFig="Fig19.0" destPortFig="Fig9.0" sourceFigNode="Fig19" destFigNode="Fig9" TupleStreamDef WindowStreamDef filter : Boolean outputProgram : String inputOrderKeyList : TupleProjection sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" WindowDef orderKeyList : TupleProjection physical : Boolean range : String offset : Integer sourcePortFig="Fig3" destPortFig="Fig1" sourceFigNode="Fig3" destFigNode="Fig1" WindowPartitionDef partitionKeyList : TupleProjection initializeProgram : String addProgram : String dropProgram : String bucketDesc : TupleDescriptor sourcePortFig="Fig5" destPortFig="Fig3" sourceFigNode="Fig5" destFigNode="Fig3" TupleStreamDef AggStreamDef groupingPrefixSize : Integer sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" AggInvocation function : AggFunction inputAttributeIndex : Integer sourcePortFig="Fig1" destPortFig="Fig3" sourceFigNode="Fig1" destFigNode="Fig3" <<enumeration>> AggFunction AGG_FUNC_SUM : AggFunction AGG_FUNC_COUNT : AggFunction AGG_FUNC_MIN : AggFunction AGG_FUNC_MAX : AggFunction AGG_FUNC_SINGLE_VALUE : AggFunction SortedAggStreamDef sourcePortFig="Fig6" destPortFig="Fig1" sourceFigNode="Fig6" destFigNode="Fig1" LhxAggStreamDef numRows : Long cndGroupByKeys : Long sourcePortFig="Fig8" destPortFig="Fig1" sourceFigNode="Fig8" destFigNode="Fig1" LbmSortedAggStreamDef sourcePortFig="Fig10" destPortFig="Fig6" sourceFigNode="Fig10" destFigNode="Fig6" TupleStreamDef IndexStreamDef sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" LbmSplicerStreamDef insertRowCountParamId : Integer writeRowCountParamId : Integer createNewIndex : Boolean IndexSearchDef uniqueKey : Boolean outerJoin : Boolean inputKeyProj : TupleProjection inputJoinProj : TupleProjection inputDirectiveProj : TupleProjection prefetch : Boolean LbmSearchStreamDef rowLimitParamId : Integer startRidParamId : Integer sourcePortFig="Fig5" destPortFig="Fig4" sourceFigNode="Fig5" destFigNode="Fig4" IndexScanDef outputProj : TupleProjection sourcePortFig="Fig7" destPortFig="Fig1" sourceFigNode="Fig7" destFigNode="Fig1" sourcePortFig="Fig4" destPortFig="Fig7" sourceFigNode="Fig4" destFigNode="Fig7" LbmNormalizerStreamDef sourcePortFig="Fig10" destPortFig="Fig0" sourceFigNode="Fig10" destFigNode="Fig0" LbmChopperStreamDef ridLimitParamId : Integer sourcePortFig="Fig12" destPortFig="Fig0" sourceFigNode="Fig12" destFigNode="Fig0" LbmUnionStreamDef ridLimitParamId : Integer consumerSridParamId : Integer segmentLimitParamId : Integer sourcePortFig="Fig14" destPortFig="Fig0" sourceFigNode="Fig14" destFigNode="Fig0" LcsRowScanStreamDef outputProj : TupleProjection isFullScan : Boolean hasExtraFilter : Boolean residualFilterColumns : TupleProjection samplingMode : TableSamplingMode samplingRate : Float samplingRepeatable : Boolean samplingRepeatableSeed : Integer samplingClumps : Integer samplingRowCount : Long sourcePortFig="Fig16" destPortFig="Fig0" sourceFigNode="Fig16" destFigNode="Fig0" LbmGeneratorStreamDef insertRowCountParamId : Integer createIndex : Boolean sourcePortFig="Fig18" destPortFig="Fig16" sourceFigNode="Fig18" destFigNode="Fig16" LbmBitOpStreamDef rowLimitParamId : Integer startRidParamId : Integer sourcePortFig="Fig20" destPortFig="Fig0" sourceFigNode="Fig20" destFigNode="Fig0" LbmMinusStreamDef sourcePortFig="Fig22" destPortFig="Fig20" sourceFigNode="Fig22" destFigNode="Fig20" LbmIntersectStreamDef sourcePortFig="Fig24" destPortFig="Fig20" sourceFigNode="Fig24" destFigNode="Fig20" IndexAccessorDef rootPageId : Long segmentId : Long indexId : Long tupleDesc : TupleDescriptor rootPageIdParamId : Integer readOnlyCommittedData : Boolean sourcePortFig="Fig1" destPortFig="Fig26" sourceFigNode="Fig1" destFigNode="Fig26" sourcePortFig="Fig18" destPortFig="Fig26" sourceFigNode="Fig18" destFigNode="Fig26" LbmSortedAggStreamDef sourcePortFig="Fig3.0" destPortFig="Fig0.0" sourceFigNode="Fig3" destFigNode="Fig0" SplicerIndexAccessorDef sourcePortFig="Fig31.0" destPortFig="Fig26.0" sourceFigNode="Fig31" destFigNode="Fig26" sourcePortFig="Fig3.0" destPortFig="Fig31.0" sourceFigNode="Fig3" destFigNode="Fig31" LcsClusterAppendStreamDef clusterColProj : TupleProjection LcsRowScanStreamDef outputProj : TupleProjection isFullScan : Boolean hasExtraFilter : Boolean residualFilterColumns : TupleProjection samplingMode : TableSamplingMode samplingRate : Float samplingRepeatable : Boolean samplingRepeatableSeed : Integer samplingClumps : Integer samplingRowCount : Long LcsClusterScanDef clusterTupleDesc : TupleDescriptor sourcePortFig="Fig1" destPortFig="Fig2" sourceFigNode="Fig1" destFigNode="Fig2" IndexAccessorDef rootPageId : Long segmentId : Long indexId : Long tupleDesc : TupleDescriptor rootPageIdParamId : Integer readOnlyCommittedData : Boolean sourcePortFig="Fig2" destPortFig="Fig4" sourceFigNode="Fig2" destFigNode="Fig4" TupleStreamDef sourcePortFig="Fig1" destPortFig="Fig6" sourceFigNode="Fig1" destFigNode="Fig6" IndexStreamDef sourcePortFig="Fig8" destPortFig="Fig6" sourceFigNode="Fig8" destFigNode="Fig6" sourcePortFig="Fig8" destPortFig="Fig4" sourceFigNode="Fig8" destFigNode="Fig4" sourcePortFig="Fig0" destPortFig="Fig8" sourceFigNode="Fig0" destFigNode="Fig8" LcsClusterReplaceStreamDef sourcePortFig="Fig12" destPortFig="Fig0" sourceFigNode="Fig12" destFigNode="Fig0" TupleDescriptor TupleAttrDescriptor typeOrdinal : Integer isNullable : Boolean byteLength : Integer sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" TupleProjection TupleAttrProjection attributeIndex : Integer sourcePortFig="Fig3" destPortFig="Fig4" sourceFigNode="Fig3" destFigNode="Fig4" TupleAccessor minByteLength : Integer bitFieldOffset : Integer TupleAttrAccessor nullBitIndex : Integer fixedOffset : Integer endIndirectOffset : Integer bitValueIndex : Integer sourcePortFig="Fig6" destPortFig="Fig7" sourceFigNode="Fig6" destFigNode="Fig7" Handle longHandle : Long DbHandle sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" TxnHandle sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" SvptHandle sourcePortFig="Fig5" destPortFig="Fig0" sourceFigNode="Fig5" destFigNode="Fig0" StreamGraphHandle sourcePortFig="Fig7" destPortFig="Fig0" sourceFigNode="Fig7" destFigNode="Fig0" StreamHandle sourcePortFig="Fig9" destPortFig="Fig0" sourceFigNode="Fig9" destFigNode="Fig0" CmdOpenDatabase createDatabase : Boolean params : DatabaseParam resultRecoveryRequired : Boolean sourcePortFig="Fig11" destPortFig="Fig1" sourceFigNode="Fig11" destFigNode="Fig1" DatabaseCmd sourcePortFig="Fig13" destPortFig="Fig1" sourceFigNode="Fig13" destFigNode="Fig1" CmdBeginTxn readOnly : Boolean TxnCmd sourcePortFig="Fig16" destPortFig="Fig3" sourceFigNode="Fig16" destFigNode="Fig3" CmdSavepoint sourcePortFig="Fig18" destPortFig="Fig5" sourceFigNode="Fig18" destFigNode="Fig5" sourcePortFig="Fig18" destPortFig="Fig16" sourceFigNode="Fig18" destFigNode="Fig16" CmdCreateExecutionStreamGraph sourcePortFig="Fig21" destPortFig="Fig7" sourceFigNode="Fig21" destFigNode="Fig7" sourcePortFig="Fig21" destPortFig="Fig16" sourceFigNode="Fig21" destFigNode="Fig16" TupleStreamGraphCmd sourcePortFig="Fig24" destPortFig="Fig7" sourceFigNode="Fig24" destFigNode="Fig7" CmdCreateStreamHandle streamName : String input : Boolean sourcePortFig="Fig26" destPortFig="Fig9" sourceFigNode="Fig26" destFigNode="Fig9" sourcePortFig="Fig26" destPortFig="Fig24" sourceFigNode="Fig26" destFigNode="Fig24" IndexCmd sourcePortFig="Fig29" destPortFig="Fig16" sourceFigNode="Fig29" destFigNode="Fig16" CmdVersionIndexRoot sourcePortFig="Fig31" destPortFig="Fig16" sourceFigNode="Fig31" destFigNode="Fig16" BeginTxnCmd sourcePortFig="Fig33" destPortFig="Fig13" sourceFigNode="Fig33" destFigNode="Fig13" sourcePortFig="Fig15.0" destPortFig="Fig33.0" sourceFigNode="Fig15" destFigNode="Fig33" sourcePortFig="Fig33.0" destPortFig="Fig3" sourceFigNode="Fig33" destFigNode="Fig3" CmdBeginTxnWithCsn sourcePortFig="Fig37" destPortFig="Fig33" sourceFigNode="Fig37" destFigNode="Fig33" CsnHandle sourcePortFig="Fig39" destPortFig="Fig0" sourceFigNode="Fig39" destFigNode="Fig0" sourcePortFig="Fig37.0" destPortFig="Fig39.0" sourceFigNode="Fig37" destFigNode="Fig39" CsnHandleReturningCmd sourcePortFig="Fig42.0" destPortFig="Fig39.0" sourceFigNode="Fig42" destFigNode="Fig39" CmdGetLastCommittedTxnId sourcePortFig="Fig44.0" destPortFig="Fig13.0" sourceFigNode="Fig44" destFigNode="Fig13" CmdGetTxnCsn sourcePortFig="Fig46" destPortFig="Fig42" sourceFigNode="Fig46" destFigNode="Fig42" sourcePortFig="Fig46.0" destPortFig="Fig16.0" sourceFigNode="Fig46" destFigNode="Fig16" sourcePortFig="Fig44.0" destPortFig="Fig42.0" sourceFigNode="Fig44" destFigNode="Fig42" TupleStreamDef CalcTupleStreamDef program : String filter : Boolean sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" CollectTupleStreamDef sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" UncollectTupleStreamDef sourcePortFig="Fig5" destPortFig="Fig0" sourceFigNode="Fig5" destFigNode="Fig0" ReshapeStreamDef compareOp : CompOperator tupleCompareBytesBase64 : String inputCompareProjection : TupleProjection outputProjection : TupleProjection sourcePortFig="Fig7" destPortFig="Fig0" sourceFigNode="Fig7" destFigNode="Fig0" <<enumeration>> CompOperator COMP_NOOP : CompOperator COMP_EQ : CompOperator COMP_NE : CompOperator COMP_LT : CompOperator COMP_LE : CompOperator COMP_GT : CompOperator COMP_GE : CompOperator ReshapeParameter dynamicParamId : Integer compareOffset : Integer outputParam : Boolean sourcePortFig="Fig7.0" destPortFig="Fig10.0" sourceFigNode="Fig7" destFigNode="Fig10" AuthId Grant action : String withGrantOption : Boolean sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" <<enumeration>> PrivilegedAction SELECT : PrivilegedAction INSERT : PrivilegedAction UPDATE : PrivilegedAction DELETE : PrivilegedAction EXECUTE : PrivilegedAction REFERENCES : PrivilegedAction TRIGGER : PrivilegedAction INHERIT_ROLE : PrivilegedAction CREATION : PrivilegedAction User sourcePortFig="Fig5" destPortFig="Fig0" sourceFigNode="Fig5" destFigNode="Fig0" Role sourcePortFig="Fig7" destPortFig="Fig0" sourceFigNode="Fig7" destFigNode="Fig0" Namespace sourcePortFig="Fig5" destPortFig="Fig9" sourceFigNode="Fig5" destFigNode="Fig9" ModelElement sourcePortFig="Fig1" destPortFig="Fig11" sourceFigNode="Fig1" destFigNode="Fig11" sourcePortFig="Fig0" destPortFig="Fig11" sourceFigNode="Fig0" destFigNode="Fig11" Element sourcePortFig="Fig1" destPortFig="Fig14" sourceFigNode="Fig1" destFigNode="Fig14" AnnotatedElement description : String lineageId : String creationTimestamp : String modificationTimestamp : String sourcePortFig="Fig0" destPortFig="Fig16" sourceFigNode="Fig0" destFigNode="Fig16" ModelElement Catalog SQLIndex SQLIndexColumn NamedColumnSet DataWrapper libraryFile : String language : String foreign : Boolean sourcePortFig="Fig5" destPortFig="Fig0" sourceFigNode="Fig5" destFigNode="Fig0" DataServer type : String version : String sourcePortFig="Fig5" destPortFig="Fig7" sourceFigNode="Fig5" destFigNode="Fig7" sourcePortFig="Fig7" destPortFig="Fig1" sourceFigNode="Fig7" destFigNode="Fig1" ElementWithStorageOptions sourcePortFig="Fig5" destPortFig="Fig10" sourceFigNode="Fig5" destFigNode="Fig10" sourcePortFig="Fig7" destPortFig="Fig10" sourceFigNode="Fig7" destFigNode="Fig10" BaseColumnSet allowedAccess : String sourcePortFig="Fig7" destPortFig="Fig13" sourceFigNode="Fig7" destFigNode="Fig13" sourcePortFig="Fig13" destPortFig="Fig4" sourceFigNode="Fig13" destFigNode="Fig4" sourcePortFig="Fig13" destPortFig="Fig10" sourceFigNode="Fig13" destFigNode="Fig10" StorageOption name : String value : String sourcePortFig="Fig10" destPortFig="Fig17" sourceFigNode="Fig10" destFigNode="Fig17" AnnotatedElement sourcePortFig="Fig10" destPortFig="Fig19" sourceFigNode="Fig10" destFigNode="Fig19" LocalIndex isClustered : Boolean storageId : String analyzeTime : String pageCount : Long isInvalid : Boolean sourcePortFig="Fig21" destPortFig="Fig2" sourceFigNode="Fig21" destFigNode="Fig2" sourcePortFig="Fig21" destPortFig="Fig19" sourceFigNode="Fig21" destFigNode="Fig19" LocalIndexColumn ordinal : Integer sourcePortFig="Fig24" destPortFig="Fig3" sourceFigNode="Fig24" destFigNode="Fig3" StoredTable sourcePortFig="Fig26" destPortFig="Fig13" sourceFigNode="Fig26" destFigNode="Fig13" ForeignTable sourcePortFig="Fig28" destPortFig="Fig26" sourceFigNode="Fig28" destFigNode="Fig26" LocalTable sourcePortFig="Fig30" destPortFig="Fig26" sourceFigNode="Fig30" destFigNode="Fig26" StoredColumn generatedAlways : Boolean isDeclaredNullable : Boolean sourcePortFig="Fig32" destPortFig="Fig10" sourceFigNode="Fig32" destFigNode="Fig10" AbstractColumn sourcePortFig="Fig32" destPortFig="Fig34" sourceFigNode="Fig32" destFigNode="Fig34" AbstractColumnSet modality : ModalityType analyzeTime : String rowCount : Long lastAnalyzeRowCount : Long deletedRowCount : Long sourcePortFig="Fig13" destPortFig="Fig36" sourceFigNode="Fig13" destFigNode="Fig36" Table sourcePortFig="Fig26" destPortFig="Fig38" sourceFigNode="Fig26" destFigNode="Fig38" Label commitSequenceNumber : Long sourcePortFig="Fig40.0" destPortFig="Fig19.0" sourceFigNode="Fig40" destFigNode="Fig19" sourcePortFig="Fig40.0" destPortFig="Fig0.0" sourceFigNode="Fig40" destFigNode="Fig0" RowCountStatistics dmlTimestamp : String rowCount : Long deletedRowCount : Long analyzeTimestamp : String analyzeRowCount : Long sourcePortFig="Fig36.0" destPortFig="Fig43.0" sourceFigNode="Fig36" destFigNode="Fig43" IndexStatistics analyzeTime : String pageCount : Long sourcePortFig="Fig21.0" destPortFig="Fig45.0" sourceFigNode="Fig21" destFigNode="Fig45" sourcePortFig="Fig40.0" destPortFig="Fig40.0" sourceFigNode="Fig40" destFigNode="Fig40" SystemBackup type : BackupType commitSequenceNumber : Long startTimestamp : String endTimestamp : String status : BackupStatusType <<enumeration>> BackupType FULL : BackupType LAST : BackupType <<enumeration>> BackupStatusType COMPLETED : BackupStatusType PENDING : BackupStatusType ViewColumn StoredColumn generatedAlways : Boolean isDeclaredNullable : Boolean AbstractColumn sourcePortFig="Fig1" destPortFig="Fig2" sourceFigNode="Fig1" destFigNode="Fig2" sourcePortFig="Fig0" destPortFig="Fig2" sourceFigNode="Fig0" destFigNode="Fig2" ColumnHistogram analyzeTime : String percentageSampled : Float barCount : Integer rowsPerBar : Long rowsLastBar : Long sampleSize : Long distinctValueCount : Long distinctValueCountEstimated : Boolean sourcePortFig="Fig2" destPortFig="Fig5" sourceFigNode="Fig2" destFigNode="Fig5" ColumnHistogramBar startingValue : String valueCount : Long ordinal : Integer sourcePortFig="Fig5" destPortFig="Fig7" sourceFigNode="Fig5" destFigNode="Fig7" AbstractKeyConstraint AbstractUniqueConstraint sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" AnnotatedElement description : String lineageId : String creationTimestamp : String modificationTimestamp : String sourcePortFig="Fig0" destPortFig="Fig3" sourceFigNode="Fig0" destFigNode="Fig3" UniqueKeyConstraint sourcePortFig="Fig5" destPortFig="Fig1" sourceFigNode="Fig5" destFigNode="Fig1" PrimaryKeyConstraint sourcePortFig="Fig7" destPortFig="Fig1" sourceFigNode="Fig7" destFigNode="Fig1" KeyComponent ordinal : Integer sourcePortFig="Fig0" destPortFig="Fig9" sourceFigNode="Fig0" destFigNode="Fig9" AbstractAttribute ordinal : Integer sourcePortFig="Fig11" destPortFig="Fig9" sourceFigNode="Fig11" destFigNode="Fig9" ModelElement sourcePortFig="Fig9" destPortFig="Fig13" sourceFigNode="Fig9" destFigNode="Fig13" sourcePortFig="Fig0" destPortFig="Fig13" sourceFigNode="Fig0" destFigNode="Fig13" UniqueConstraint sourcePortFig="Fig1" destPortFig="Fig16" sourceFigNode="Fig1" destFigNode="Fig16" PrimaryKey sourcePortFig="Fig7" destPortFig="Fig18" sourceFigNode="Fig7" destFigNode="Fig18" AnnotatedElement description : String lineageId : String creationTimestamp : String modificationTimestamp : String Routine invocationName : String externalName : String newSavepointLevel : Boolean dynamicResultSetCount : Integer staticDispatch : Boolean parameterStyle : String impersonateDefiner : Boolean deterministic : Boolean dataAccess : RoutineDataAccess calledOnNullInput : Boolean language : String isUdx : Boolean dynamicFunction : Boolean sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" <<enumeration>> ExtensionLanguage SQL : ExtensionLanguage JAVA : ExtensionLanguage AbstractTypedElement sourcePortFig="Fig4" destPortFig="Fig0" sourceFigNode="Fig4" destFigNode="Fig0" RoutineParameter ordinal : Integer precision : Integer scale : Integer length : Integer collationName : String characterSetName : String sourcePortFig="Fig6" destPortFig="Fig4" sourceFigNode="Fig6" destFigNode="Fig4" ColumnSet sourcePortFig="Fig1" destPortFig="Fig8" sourceFigNode="Fig1" destFigNode="Fig8" Procedure sourcePortFig="Fig1" destPortFig="Fig10" sourceFigNode="Fig1" destFigNode="Fig10" ModelElement sourcePortFig="Fig4" destPortFig="Fig12" sourceFigNode="Fig4" destFigNode="Fig12" SQLParameter sourcePortFig="Fig6" destPortFig="Fig14" sourceFigNode="Fig6" destFigNode="Fig14" <<enumeration>> RoutineParameterStyle RPS_SQL : RoutineParameterStyle RPS_GENERAL : RoutineParameterStyle RPS_JAVA : RoutineParameterStyle RPS_JAVA_FARRAGO : RoutineParameterStyle <<enumeration>> RoutineDataAccess RDA_NO_SQL : RoutineDataAccess RDA_CONTAINS_SQL : RoutineDataAccess RDA_READS_SQL_DATA : RoutineDataAccess RDA_MODIFIES_SQL_DATA : RoutineDataAccess ColumnListRoutineParameter sourceCursorName : String sourcePortFig="Fig18.0" destPortFig="Fig6.0" sourceFigNode="Fig18" destFigNode="Fig6" SampleDataset name : String baselineTimestamp : String ColumnSet sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" AbstractColumnSet modality : ModalityType analyzeTime : String rowCount : Long lastAnalyzeRowCount : Long deletedRowCount : Long sourcePortFig="Fig0" destPortFig="Fig3" sourceFigNode="Fig0" destFigNode="Fig3" sourcePortFig="Fig3" destPortFig="Fig1" sourceFigNode="Fig3" destFigNode="Fig1" sourcePortFig="Fig3" destPortFig="Fig1" sourceFigNode="Fig3" destFigNode="Fig1" AnnotatedElement description : String lineageId : String creationTimestamp : String modificationTimestamp : String TagAnnotation name : String value : String sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" LocalCatalog sourcePortFig="Fig3" destPortFig="Fig0" sourceFigNode="Fig3" destFigNode="Fig0" Catalog sourcePortFig="Fig3" destPortFig="Fig5" sourceFigNode="Fig3" destFigNode="Fig5" Schema LocalSchema sourcePortFig="Fig8" destPortFig="Fig7" sourceFigNode="Fig8" destFigNode="Fig7" sourcePortFig="Fig8" destPortFig="Fig0" sourceFigNode="Fig8" destFigNode="Fig0" LocalView originalDefinition : String sourcePortFig="Fig11" destPortFig="Fig0" sourceFigNode="Fig11" destFigNode="Fig0" View sourcePortFig="Fig11" destPortFig="Fig13" sourceFigNode="Fig11" destFigNode="Fig13" AbstractColumnSet modality : ModalityType analyzeTime : String rowCount : Long lastAnalyzeRowCount : Long deletedRowCount : Long sourcePortFig="Fig11" destPortFig="Fig15" sourceFigNode="Fig11" destFigNode="Fig15" ColumnSet sourcePortFig="Fig15" destPortFig="Fig17" sourceFigNode="Fig15" destFigNode="Fig17" sourcePortFig="Fig15" destPortFig="Fig17" sourceFigNode="Fig15" destFigNode="Fig17" SQLPathElement searchedSchemaCatalogName : String searchedSchemaName : String sourcePortFig="Fig8" destPortFig="Fig20" sourceFigNode="Fig8" destFigNode="Fig20" Namespace Jar url : String deploymentState : Integer modelExtension : Boolean sourcePortFig="Fig23" destPortFig="Fig22" sourceFigNode="Fig23" destFigNode="Fig22" sourcePortFig="Fig23" destPortFig="Fig0" sourceFigNode="Fig23" destFigNode="Fig0" AbstractColumn StoredColumn generatedAlways : Boolean isDeclaredNullable : Boolean sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" AbstractTypedElement AbstractAttribute ordinal : Integer sourcePortFig="Fig4" destPortFig="Fig3" sourceFigNode="Fig4" destFigNode="Fig3" sourcePortFig="Fig0" destPortFig="Fig4" sourceFigNode="Fig0" destFigNode="Fig4" SequenceGenerator baseValue : Long increment : Long minValue : Long maxValue : Long cycle : Boolean expired : Boolean sourcePortFig="Fig1" destPortFig="Fig7" sourceFigNode="Fig1" destFigNode="Fig7" sourcePortFig="Fig7" destPortFig="Fig3" sourceFigNode="Fig7" destFigNode="Fig3" ModelElement sourcePortFig="Fig3" destPortFig="Fig10" sourceFigNode="Fig3" destFigNode="Fig10" AnnotatedElement sourcePortFig="Fig3" destPortFig="Fig12" sourceFigNode="Fig3" destFigNode="Fig12" SQLDataType SQLCollectionType sourcePortFig="Fig1" destPortFig="Fig0" sourceFigNode="Fig1" destFigNode="Fig0" SQLMultisetType sourcePortFig="Fig3" destPortFig="Fig1" sourceFigNode="Fig3" destFigNode="Fig1" SQLArrayType sourcePortFig="Fig5" destPortFig="Fig1" sourceFigNode="Fig5" destFigNode="Fig1" AnnotatedElement UserDefinedType isFinal : Boolean sourcePortFig="Fig8" destPortFig="Fig0" sourceFigNode="Fig8" destFigNode="Fig0" sourcePortFig="Fig8" destPortFig="Fig7" sourceFigNode="Fig8" destFigNode="Fig7" SQLStructuredType SQLRowType sourcePortFig="Fig12" destPortFig="Fig11" sourceFigNode="Fig12" destFigNode="Fig11" SQLObjectType sourcePortFig="Fig14" destPortFig="Fig11" sourceFigNode="Fig14" destFigNode="Fig11" sourcePortFig="Fig14" destPortFig="Fig8" sourceFigNode="Fig14" destFigNode="Fig8" SQLDistinguishedType collationName : String characterSetName : String sourcePortFig="Fig17" destPortFig="Fig8" sourceFigNode="Fig17" destFigNode="Fig8" SQLDistinctType sourcePortFig="Fig17" destPortFig="Fig19" sourceFigNode="Fig17" destFigNode="Fig19" AbstractTypedElement sourcePortFig="Fig17" destPortFig="Fig21" sourceFigNode="Fig17" destFigNode="Fig21" AbstractAttribute ordinal : Integer sourcePortFig="Fig23" destPortFig="Fig21" sourceFigNode="Fig23" destFigNode="Fig21" SQLTypeAttribute sourcePortFig="Fig25" destPortFig="Fig23" sourceFigNode="Fig25" destFigNode="Fig23" UserDefinedOrdering category : UserDefinedOrderingCategory full : Boolean sourcePortFig="Fig8" destPortFig="Fig27" sourceFigNode="Fig8" destFigNode="Fig27" Namespace sourcePortFig="Fig27" destPortFig="Fig29" sourceFigNode="Fig27" destFigNode="Fig29" <<enumeration>> UserDefinedOrderingCategory UDOC_STATE : UserDefinedOrderingCategory UDOC_RELATIVE : UserDefinedOrderingCategory UDOC_MAP : UserDefinedOrderingCategory <<enumeration>> RecoveryType ALTER_TABLE_ADD_COLUMN : RecoveryType RecoveryReference recoveryType : RecoveryType Namespace sourcePortFig="Fig1.0" destPortFig="Fig2.0" sourceFigNode="Fig1" destFigNode="Fig2" A RecoveryReference connects to model elements via Dependency. The model elements are suppliers and the RecoveryReference is the client (and also the owner of the dependency, which is why it inherits from Namespace). eigenbase-farrago-0.9.0/catalog/xmi/cwm-1.1.xml0000444000175000017500000460226011173714170021003 0ustar drazzibdrazzib org.omg.cwm.objectmodel CWM 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 -1 true true 0 -1 false true 0 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 true true UmlConstraint 0 1 false false 1 -1 false true 1 -1 false true 1 1 false false 0 1 false false 1 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 0 1 false false 0 1 false false umlValue ck_ ok_ sk_ vk_ 0 1 false false 0 -1 true true 1 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 0 -1 true true 0 -1 false true umlConstraint 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 1 1 false false 1 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 1 false false 0 -1 false true org.omg.cwm.objectmodel CWM 1 1 false false 0 1 false false umlValue 1 1 false false 0 -1 true true 1 1 false false 0 -1 true true 0 -1 true true UmlInterface 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false pdk_ 0 1 false false 0 -1 true true 0 -1 true true 0 1 false false 0 1 false false 0 -1 true true 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false org.omg.cwm.objectmodel CWM 1 1 false false 1 1 false false 1 1 false false 1 1 false false ak_ 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true org.omg.cwm.objectmodel CWM 1 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true UmlObject 0 -1 false true 1 1 false false cwmlValue 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 1 1 false false 0 -1 false true CWM org.omg.cwm.foundation 1 1 false false 0 -1 true true 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 true true 0 -1 true true 0 -1 false true 0 -1 true true 0 -1 true true 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 -1 true true 0 -1 false true 0 -1 true true 0 -1 false true 0 -1 true true 0 -1 false true 0 -1 true true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 true true 0 -1 false true CWM org.omg.cwm.foundation 1 1 false false 1 -1 false true 0 1 false false 1 1 false false umlValue typedef Foundation.DataTypes.ProcedureExpression QueryExpression; 1 1 false false 0 1 false false CwmUnion 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 -1 false true 0 1 false false 0 -1 false true CWM org.omg.cwm.foundation 0 1 false false 0 1 false false 0 1 false false 1 1 false false umlValue 1 1 false false 0 -1 true true 1 1 false false 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 0 -1 true true 1 1 false false 0 -1 false true CWM org.omg.cwm.foundation 1 -1 true true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 -1 true true 1 1 false false 1 -1 true true 1 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 true true 1 -1 true true 0 -1 false true 1 -1 true true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true org.omg.cwm.foundation CWM 0 -1 false true 0 -1 true false 0 -1 true false 0 1 false false 0 1 false false 0 -1 false true 0 1 false false 0 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true CWM org.omg.cwm.foundation 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true CWMRDB org.omg.cwm.resource 1 1 false false 1 1 false false RelationalColumnSet CwmColumnSet 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 1 false false 0 -1 true true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false CwmRowSet 0 -1 false true 0 -1 false true 1 1 false false 0 -1 true true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false CWMREC org.omg.cwm.resource 0 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 0 -1 true true CwmRecordSet 0 -1 false true 0 -1 true true CWMMDB org.omg.cwm.resource 0 -1 true true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false CwmDimension 0 -1 false true 1 1 false false 1 1 false false CwmMemberSet 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 true true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false CWMXML org.omg.cwm.resource 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 true true 0 1 false false xmlAttribute 1 1 false false 0 1 false false XmlAttribute XmlAttribute 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false xml_ 1 1 false false 0 -1 false true 1 1 false false XmlElement 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false CWMTFM org.omg.cwm.analysis 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 1 -1 false true 1 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 -1 false true 1 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 -1 false true 1 -1 false true 0 1 false false tfm_ 1 -1 false true 1 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 -1 false true 1 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 1 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true 1 -1 false true 0 -1 false true CWMOLAP org.omg.cwm.analysis 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 true true 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 1 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 1 false false 0 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 1 1 false false 1 1 false false 0 -1 true true 0 -1 true true 1 -1 false true 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 true true 0 -1 false true 1 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 0 -1 true true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 1 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 true true 0 1 false false 0 -1 true true 0 1 false false 0 -1 false true 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 true true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false org.omg.cwm.analysis CWMMIN 0 1 false false 1 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false miningAttribute 1 1 false false 1 1 false false 1 1 false false 1 -1 false true 1 1 false false 1 1 false false 0 1 false false 1 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 -1 false true 0 -1 false true 0 1 false false 0 1 false false 0 -1 false true 1 1 false false 1 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 0 1 false false 1 -1 false true 1 1 false false 0 -1 false true 0 1 false false 0 -1 true true org.omg.cwm.analysis CWMIV 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 1 1 false false 0 -1 false true 0 -1 false true CwmRenderedObjectSet 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false CWMBUS org.omg.cwm.analysis 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true CWMWHP org.omg.cwm.management 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 -1 true true 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 0 -1 true true 0 -1 false true 1 1 false false CWMWHO org.omg.cwm.management 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false umlValue 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 -1 false true 1 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 1 false false 0 1 false false 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 -1 true true 1 -1 false true 0 -1 true true 0 1 false false 0 -1 false true org.omg.cwmx.foundation CWMXER 0 1 false false 1 1 false false 1 1 false false 0 1 false false defaultValue ErAttribute ErRelationship 1 1 false false 1 1 false false 1 1 false false 0 1 false false ErModel 0 1 false false 0 1 false false 0 1 false false 0 -1 false true CWMXCOBOL org.omg.cwmx.resource 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 4 true true 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 0 -1 false false 1 1 false false 1 1 false false 0 1 false false 0 -1 true true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 1 false false 0 -1 true true 0 -1 true true 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false at_ bk_ fo_ lk_ li_ sk_ 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 4 true true 1 1 false false 0 -1 true true 1 1 false false 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 true true 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 true true 0 -1 false true CWMXDMSII org.omg.cwmx.resource 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 48 false true 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 -1 false true 0 -1 true true 0 1 false false dmsiiSetType 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 true true 0 -1 false true 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 48 false true 0 -1 false true 0 -1 false true 1 1 false false 0 -1 true true 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true CWMXIMS org.omg.cwmx.resource 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 -1 true true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 1 false false 0 32 false true 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 0 2 false true 0 1 false false 0 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true ImsField 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 1 false false 0 -1 false true 1 1 false false 0 32 false true 1 1 false false 0 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 16 false true 0 -1 false true 0 -1 false true 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 0 1 false false 0 5 false true 0 5 false true 0 5 false true 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 0 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 32 false true 1 1 false false 0 16 false true 0 1 false false 0 5 false true 0 -1 false true 0 5 false true 0 -1 false true 0 -1 false true 0 5 false true 0 -1 false true 1 1 false false 0 -1 false true 0 2 false true 0 1 false false 0 -1 false true 0 32 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 -1 true true 1 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 0 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 0 -1 false true 0 1 false false 0 -1 false true CWMXESSB org.omg.cwmx.resource 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false ess_ 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false CWMXExpress org.omg.cwmx.resource 1 1 false false 0 1 false false 1 1 false false 0 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 0 1 false false 0 1 false false 0 1 false false 1 1 false false 0 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 -1 false true 0 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 1 false false 1 1 false false 1 1 false false 0 -1 false true 1 1 false false 0 -1 false true org.omg.cwmx.analysis CWMXIS 1 1 false false 0 -1 false true 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 1 1 false false 0 -1 false true 0 -1 false true 0 -1 false true 1 1 false false 1 1 false false 1 1 false false 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 0 1 false false 0 -1 false true 1 1 false false 0 -1 false true 0 -1 false true 1 -1 false true org.omg.cwmx.analysis CWMXIR 1 1 false false 0 -1 false true 0 -1 false true 0 1 false false eigenbase-farrago-0.9.0/catalog/xmi/movePluginPackage.xsl0000444000175000017500000000162311173714170023317 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/xmi/maskIds.xsl0000444000175000017500000000214711173714170021313 0ustar drazzibdrazzib XXX XXX XXX XXX XXX eigenbase-farrago-0.9.0/catalog/templates/0000755000175000017500000000000011173714170020367 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/catalog/templates/EnkiEhCache.xml0000444000175000017500000000027111173714170023176 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/catalog/templates/PostgresRepos.properties0000444000175000017500000000230611173714170025323 0ustar drazzibdrazzib# $Id: //open/dev/farrago/catalog/templates/PostgresRepos.properties#2 $ # Repository storage properties for PostgreSQL # Configure Netbeans MDR usage org.eigenbase.enki.implementationType=NETBEANS_MDR # Class name of MDR storage plugin factory org.netbeans.mdr.storagemodel.StorageFactoryClassName=\ org.netbeans.mdr.persistence.jdbcimpl.JdbcStorageFactory # JDBC driver MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.driverClassName=\ org.postgresql.Driver # URL for database storage MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.url=\ jdbc:postgresql://localhost/test # user name MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.userName=postgres # password MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.password= # schema name MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.schemaName=\ FarragoCatalog # datatype to use for storing binary objects MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.datatype.streamable=\ bytea # Query for duplicates to prevent transaction aborts. # This can be disabled for some future PostgreSQL version # with real subtransaction support. MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.queryDuplicates=true eigenbase-farrago-0.9.0/catalog/templates/MysqlHibernateRepos.properties0000444000175000017500000000473211173714170026451 0ustar drazzibdrazzib# Hibernate repository configuration file. # Configure Hibernate usage org.eigenbase.enki.implementationType=ENKI_HIBERNATE # Configure mysql connection org.eigenbase.enki.hibernate.connection.driver_class=com.mysql.jdbc.Driver org.eigenbase.enki.hibernate.connection.url=jdbc:mysql://localhost:3306/{SCHEMA} org.eigenbase.enki.hibernate.connection.username=root org.eigenbase.enki.hibernate.connection.password= org.eigenbase.enki.hibernate.createSchema=VIEW org.eigenbase.enki.hibernate.tablePrefix=FEM_ hibernate.current_session_context_class=thread hibernate.transaction.factory_class=org.hibernate.transaction.JDBCTransactionFactory # N.B.: If running inside a J2EE container (such as JBoss), delete # hibernate.transaction.factory_class and use the following (modified to # match your container): # hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup # Hibernate configuration parameters. These property names are the # property names available via org.hibernate.cfg.Configuration's # setProperty(String, String) method. # Configure Hibernate's SQL dialect for mysql hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect # Override cache settings from hibernate-base-config.xml hibernate.cache.use_second_level_cache=true hibernate.cache.use_query_cache=true # Flush session after ever N type lookup insertions org.eigenbase.enki.hibernate.typeLookupFlushSize=250 ## Allows multiple session factories per VM (as opposed to Hibernate's built-in ## EhCacheProvider) hibernate.cache.provider_class=net.sf.ehcache.hibernate.EhCacheProvider net.sf.ehcache.configurationResourceName=/FarragoEhCache.xml # Use batch fetching hibernate.default_batch_fetch_size=25 hibernate.jdbc.batch_size=25 # Dump SQL to stdout. This breaks diff-based unit tests. An alternative is # setting "org.hibernate.SQL.level=FINE" in trace properties. #hibernate.show_sql=true # Configure (for Farrago dev environment) SQL to delete and create storage # These properties are used only at build time and may be deleted from # production storage configurations. net.sf.farrago.dev.dropStorage=DROP DATABASE IF EXISTS {SCHEMA}; net.sf.farrago.dev.createStorage=CREATE DATABASE {SCHEMA}; net.sf.farrago.dev.connection.driver_class=com.mysql.jdbc.Driver net.sf.farrago.dev.connection.url=jdbc:mysql://localhost:3306/ net.sf.farrago.dev.connection.schema.url=jdbc:mysql://localhost:3306/{SCHEMA} net.sf.farrago.dev.connection.username=root net.sf.farrago.dev.connection.password= eigenbase-farrago-0.9.0/catalog/templates/HsqldbRepos.properties0000444000175000017500000000176211173714170024737 0ustar drazzibdrazzib# $Id: //open/dev/farrago/catalog/templates/HsqldbRepos.properties#3 $ # Repository storage properties for hsqldb # Configure Netbeans MDR usage org.eigenbase.enki.implementationType=NETBEANS_MDR # Class name of MDR storage plugin factory org.netbeans.mdr.storagemodel.StorageFactoryClassName=\ org.netbeans.mdr.persistence.jdbcimpl.JdbcStorageFactory # JDBC driver for hsqldb MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.driverClassName=\ org.hsqldb.jdbcDriver # URL for database storage MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.url=\ jdbc:hsqldb:${FARRAGO_CATALOG_DIR}/FarragoCatalog;shutdown=true # user name MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.userName=SA # password MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.password= # schema name (used as a table prefix) MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.schemaName=MDR # schema authorization name MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.schemaAuthName=DBA eigenbase-farrago-0.9.0/catalog/templates/BTreeRepos.properties0000444000175000017500000000110011173714170024505 0ustar drazzibdrazzib# $Id: //open/dev/farrago/catalog/templates/BTreeRepos.properties#2 $ # Repository storage properties for MDR's BTree implementation # Configure Netbeans MDR usage org.eigenbase.enki.implementationType=NETBEANS_MDR # Class name of MDR storage plugin factory org.netbeans.mdr.storagemodel.StorageFactoryClassName=\ org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactory # Base filename (without extension) for location of stored files # (MDR creates several files derived from this base name) org.netbeans.mdr.persistence.Dir=${FARRAGO_CATALOG_DIR}/FarragoCatalog eigenbase-farrago-0.9.0/catalog/templates/HsqldbHibernateRepos.properties0000444000175000017500000000477711173714170026572 0ustar drazzibdrazzib# Hibernate repository configuration file. # Configure Hibernate usage org.eigenbase.enki.implementationType=ENKI_HIBERNATE # Configure mysql connection org.eigenbase.enki.hibernate.connection.driver_class=org.hsqldb.jdbcDriver org.eigenbase.enki.hibernate.connection.url=jdbc:hsqldb:${FARRAGO_CATALOG_DIR}/FarragoCatalog;shutdown=true org.eigenbase.enki.hibernate.connection.username=SA org.eigenbase.enki.hibernate.connection.password= org.eigenbase.enki.hibernate.createSchema=VIEW org.eigenbase.enki.hibernate.tablePrefix=FEM_ hibernate.current_session_context_class=thread hibernate.transaction.factory_class=org.hibernate.transaction.JDBCTransactionFactory # N.B.: If running inside a J2EE container (such as JBoss), delete # hibernate.transaction.factory_class and use the following (modified to # match your container): # hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup # Hibernate configuration parameters. These property names are the # property names available via org.hibernate.cfg.Configuration's # setProperty(String, String) method. # Configure Hibernate's SQL dialect for mysql hibernate.dialect=org.hibernate.dialect.HSQLDialect # Override cache settings from hibernate-base-config.xml hibernate.cache.use_second_level_cache=true hibernate.cache.use_query_cache=true # Flush session after ever N type lookup insertions org.eigenbase.enki.hibernate.typeLookupFlushSize=250 ## Allows multiple session factories per VM (as opposed to Hibernate's built-in ## EhCacheProvider) hibernate.cache.provider_class=net.sf.ehcache.hibernate.EhCacheProvider net.sf.ehcache.configurationResourceName=/FarragoEhCache.xml # Use batch fetching hibernate.default_batch_fetch_size=25 hibernate.jdbc.batch_size=25 # Dump SQL to stdout. This breaks diff-based unit tests. An alternative is # setting "org.hibernate.SQL.level=FINE" in trace properties. #hibernate.show_sql=true # Configure (for Farrago dev environment) SQL to delete and create storage # These properties are used only at build time and may be deleted from # production storage configurations. net.sf.farrago.dev.dropStorage= net.sf.farrago.dev.createStorage=SET WRITE_DELAY 0; net.sf.farrago.dev.connection.driver_class=org.hsqldb.jdbcDriver net.sf.farrago.dev.connection.url=jdbc:hsqldb:${FARRAGO_CATALOG_DIR}/FarragoCatalog;shutdown=true net.sf.farrago.dev.connection.schema.url=jdbc:hsqldb:${FARRAGO_CATALOG_DIR}/FarragoCatalog;shutdown=true net.sf.farrago.dev.connection.username=SA net.sf.farrago.dev.connection.password= eigenbase-farrago-0.9.0/regressionsql/0000755000175000017500000000000011173714170017657 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/dbmanEngine0000555000175000017500000000050511173714170017112 0ustar drazzibdrazzib#!/bin/bash # $Id: //open/dev/farrago/dbmanEngine#1 $ # Run the hsqldb Database Manager tool # with an embedded Farrago engine source ./defineFarragoRuntime.sh java ${SERVER_JAVA_ARGS} org.hsqldb.util.DatabaseManagerSwing \ --driver net.sf.farrago.jdbc.engine.FarragoJdbcEngineDriver \ --url jdbc:farrago: \ --user sa \ $* eigenbase-farrago-0.9.0/examples/0000755000175000017500000000000011173714170016575 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/0000755000175000017500000000000011173714170020765 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/build.xml0000444000175000017500000000620611173714170022610 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/plannerviz/src/0000755000175000017500000000000011173714170021554 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/src/net/0000755000175000017500000000000011173714170022342 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/0000755000175000017500000000000011173714170022752 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/0000755000175000017500000000000011173714170024373 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/plannerviz/0000755000175000017500000000000011173714170026563 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/plannerviz/package.html0000444000175000017500000000110511173714170031037 0ustar drazzibdrazzib Package net.sf.farrago.plannerviz Defines a Farrago plugin for planner visualization.
Revision $Id: //open/dev/farrago/examples/plannerviz/src/net/sf/farrago/plannerviz/package.html#3 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John Pham
././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrooteigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlanVisualizer.javaeigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlanVisualizer.java0000444000175000017500000005232011173714170033700 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlanVisualizer.java#14 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2005-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plannerviz; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import org.jgrapht.*; import org.jgrapht.ext.*; import org.jgrapht.graph.*; import org.jgrapht.graph.DefaultEdge; import org.jgraph.*; import org.jgraph.graph.*; import org.jgraph.layout.*; import org.jgraph.algebra.*; import org.eigenbase.relopt.*; import org.eigenbase.rel.*; import org.eigenbase.rel.convert.*; import java.util.*; import java.util.logging.*; // TODO jvs 18-Feb-2005: avoid these two dependencies import org.eigenbase.relopt.volcano.*; import org.eigenbase.relopt.hep.*; import net.sf.farrago.trace.*; import java.util.List; /** * FarragoPlanVizualizer uses JGraph to visualize the machinations * of the planner. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlanVisualizer.java#14 $ */ public class FarragoPlanVisualizer extends JApplet implements RelOptListener, WindowListener { private static final Logger tracer = FarragoTrace.getPlannerVizTracer(); private static final int STATE_CRAWLING = 0; private static final int STATE_STEPPING = 1; private static final int STATE_WALKING = 2; private static final int STATE_RUNNING = 3; private static final int STATE_FLYING = 4; private static final int STATE_CLOSED = 5; private static final int DETAIL_LOGICAL = 1; private static final int DETAIL_PHYSICAL = 2; private static final int DETAIL_PHYSIOLOGICAL = 3; private int state; private int detail; private int currentGenerationNumber; private Object stepVar; private JFrame frame; private JScrollPane scrollPane; private JGraph graph; private GraphLayoutCache graphView; private JGraphModelAdapter graphAdapter; private ListenableDirectedGraph graphModel; private JMenuItem status; private UnionFind physicalEquivMap; private UnionFind logicalEquivMap; private double scale; private Set rels; private Map objToVertexMap; private AttributeMap normalVertexAttributes; private AttributeMap newVertexAttributes; private AttributeMap oldVertexAttributes; private AttributeMap finalVertexAttributes; private List highlightList; private String ruleName; public FarragoPlanVisualizer() { status = new JMenuItem("Building abstract plan"); JMenuBar menuBar = new JMenuBar(); addStateButton(menuBar, "CRAWL", STATE_CRAWLING); addStateButton(menuBar, "STEP", STATE_STEPPING); addStateButton(menuBar, "WALK", STATE_WALKING); addStateButton(menuBar, "RUN", STATE_RUNNING); addStateButton(menuBar, "FLY", STATE_FLYING); addZoomButton(menuBar, "ZOOMIN", 1.5); addZoomButton(menuBar, "ZOOMOUT", 1.0 / 1.5); frame = new JFrame(); frame.setJMenuBar(menuBar); frame.addWindowListener(this); frame.getContentPane().add(this); frame.setTitle("Plannerviz"); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); init(); frame.setVisible(true); stepVar = new Object(); state = STATE_CRAWLING; scale = 1; rels = new HashSet(); objToVertexMap = new HashMap(); physicalEquivMap = new UnionFind(); logicalEquivMap = new UnionFind(); highlightList = new ArrayList(); if (tracer.getLevel() == Level.FINEST) { detail = DETAIL_PHYSIOLOGICAL; } else if (tracer.getLevel() == Level.FINER) { detail = DETAIL_PHYSICAL; } else { detail = DETAIL_LOGICAL; } } private void addStateButton( JMenuBar menuBar, String name, final int newState) { JMenuItem button = new JMenuItem(name); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { changeState(newState); } }); menuBar.add(button); } private void addZoomButton( JMenuBar menuBar, String name, final double factor) { JMenuItem button = new JMenuItem(name); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { scale *= factor; graph.setScale(scale); } }); menuBar.add(button); } private void changeState(int newState) { synchronized (stepVar) { state = newState; stepVar.notifyAll(); } } // implement WindowListener public void windowClosing(WindowEvent e) { } // implement WindowListener public void windowClosed(WindowEvent e) { changeState(STATE_CLOSED); } // implement WindowListener public void windowOpened(WindowEvent e) { } // implement WindowListener public void windowIconified(WindowEvent e) { } // implement WindowListener public void windowDeiconified(WindowEvent e) { } // implement WindowListener public void windowActivated(WindowEvent e) { } // implement WindowListener public void windowDeactivated(WindowEvent e) { } // implement RelOptListener public void relChosen(RelChosenEvent event) { if (state > STATE_RUNNING) { return; } if (event.getRel() == null) { setStatus("Final plan complete"); return; } if (!includeRel(event.getRel())) { return; } setStatus("Adding node to final plan"); VisualVertex vertex = makeVertex(event.getRel()); paintVertex(vertex, finalVertexAttributes); waitForInput(); } // implement RelOptListener public void relDiscarded(RelDiscardedEvent event) { if (state == STATE_CRAWLING) { setStatus("Discarding " + event.getRel()); updateGraph(); highlightVertex(makeVertex(event.getRel()), oldVertexAttributes); waitForInput(); } rels.remove(event.getRel()); } // implement RelOptListener public void relEquivalenceFound(RelEquivalenceEvent event) { if (state > STATE_RUNNING) { return; } if (detail == DETAIL_LOGICAL) { if (event.isPhysical()) { return; } } else if (detail == DETAIL_PHYSICAL) { if (!event.isPhysical()) { return; } } if (!includeRel(event.getRel())) { return; } UnionFind equivMap; String type; if (event.isPhysical()) { type = "Physical"; equivMap = physicalEquivMap; } else { type = "Logical"; equivMap = logicalEquivMap; } // REVIEW jvs 19-Feb-2005: we intentionally create the UnionFind sets // in this order for Volcano to make sure that the representation // chosen is the equivalence class, not the original rel. Object equivSet = equivMap.find(event.getEquivalenceClass()); Object relSet = equivMap.find(event.getRel()); equivMap.union(equivSet, relSet); if (detail == DETAIL_LOGICAL) { // In this case, we don't visualize subsets, but we do // record their equivalence so that inputs get connected // correctly. if (event.getRel() instanceof RelSubset) { return; } } boolean newRel = rels.add(event.getRel()); if (event.getEquivalenceClass() instanceof HepRelVertex) { // For Hep, we don't care about equivalences much. newRel = true; } if ((state == STATE_CRAWLING) || (!newRel && (state == STATE_STEPPING))) { String newStatus; if (newRel) { newStatus = "New expression added to " + type.toLowerCase() + " equivalence class"; } else { newStatus = type + " equivalence found for " + event.getEquivalenceClass(); } if (ruleName != null) { newStatus += " by rule " + ruleName; } setStatus(newStatus); updateGraph(); highlightVertex(makeVertex(event.getRel()), newVertexAttributes); waitForInput(); } } // implement RelOptListener public void ruleAttempted(RuleAttemptedEvent event) { if (event.isBefore()) { ruleName = event.getRuleCall().getRule().toString(); } else { ruleName = null; } } // implement RelOptListener public void ruleProductionSucceeded(RuleProductionEvent event) { if (state > STATE_RUNNING) { return; } if (state == STATE_CRAWLING) { if (!event.isBefore()) { // already previewed; skip post-display return; } } if (!includeRel(event.getRel())) { return; } String verb; if (!event.isBefore()) { if (!rels.contains(event.getRel())) { // The rel didn't get registered, so it must have // matched an existing one; don't bother showing the // rule production. return; } verb = "produced"; } else { verb = "producing"; } if (state > STATE_WALKING) { updateGraph(); return; } setStatus( "Rule " + event.getRuleCall().getRule() + " " + verb + " new expression " + event.getRel()); updateGraph(); highlightRuleVertices(event); waitForInput(); } private void setStatus(String text) { status.setText(text); for (VisualVertex vertex : highlightList) { paintVertex(vertex, normalVertexAttributes); } highlightList.clear(); } private void highlightRuleVertices(RuleProductionEvent event) { if (!event.isBefore()) { highlightVertex(makeVertex(event.getRel()), newVertexAttributes); if (event.getRuleCall() instanceof HepRuleCall) { return; } } RelNode [] rels = event.getRuleCall().rels; for (RelNode rel : rels) { if (includeRel(rel)) { highlightVertex(makeVertex(rel), oldVertexAttributes); } } } private boolean includeRel(RelNode rel) { if (rel == null) { return false; } if (detail == DETAIL_LOGICAL) { if (isConverterRel(rel)) { return false; } } if (rel instanceof AbstractConverter) { return false; } return true; } private boolean isConverterRel(RelNode rel) { boolean volcano = false; if (volcano) { return (rel instanceof ConverterRel); } else { return false; } } private void highlightVertex(VisualVertex vertex, AttributeMap attributes) { paintVertex(vertex, attributes); highlightList.add(vertex); } private void paintVertex(VisualVertex vertex, AttributeMap map) { DefaultGraphCell cell = graphAdapter.getVertexCell(vertex); if (cell == null) { return; } CellView cellView = graphView.getMapping(cell, true); cellView.changeAttributes(map); graphView.cellViewsChanged(new CellView[]{cellView}); if (!graphView.isVisible(cell)) { graph.scrollCellToVisible(cell); } } private void updateGraph() { if (state != STATE_RUNNING) { graph.setVisible(false); } // update the graph model to reflect current state ++currentGenerationNumber; for (RelNode rel : rels) { VisualVertex v1 = makeVertex(rel); if (rel instanceof RelSubset) { Object set = logicalEquivMap.find(rel); if (set != rel) { VisualVertex v2 = makeVertex(set); makeEdge(v2, v1, ""); } continue; } UnionFind equivMap; if (detail == DETAIL_LOGICAL) { equivMap = logicalEquivMap; } else { equivMap = physicalEquivMap; } Object set = equivMap.find(rel); if ((set != rel) && !(set instanceof HepRelVertex)) { VisualVertex v2 = makeVertex(set); makeEdge(v2, v1, ""); } // converters can lead to cycles around subsets, so // omit the edges for their inputs if (!isConverterRel(rel)) { RelNode[] inputs = rel.getInputs(); for (int i = 0; i < inputs.length; ++i) { Object inputSet = equivMap.find(inputs[i]); if (inputSet instanceof HepRelVertex) { inputSet = ((HepRelVertex) inputSet).getCurrentRel(); } VisualVertex v2 = makeVertex(inputSet); if (inputSet != set) { String label; if (inputs.length > 1) { label = Integer.toString(i); } else { label = ""; } makeEdge(v1, v2, label); } } } } List recyclingList = new ArrayList(); // collect obsolete edges for (VisualEdge edge : graphModel.edgeSet()) { if (edge.generationNumber != currentGenerationNumber) { recyclingList.add(edge); } } // dispose of obsolete edges for (Object obj : recyclingList) { graphModel.removeEdge((VisualEdge) obj); } recyclingList.clear(); // collect roots and obsolete vertices List roots = new ArrayList(); for (VisualVertex vertex : graphModel.vertexSet()) { if (vertex.generationNumber != currentGenerationNumber) { recyclingList.add(vertex); continue; } if (graphModel.inDegreeOf(vertex) == 0) { roots.add(graphAdapter.getVertexCell(vertex)); } } // dispose of obsolete vertices for (Object obj : recyclingList) { VisualVertex visualVertex = (VisualVertex) obj; graphModel.removeVertex(visualVertex); objToVertexMap.remove(visualVertex.obj); } // compute graph layout assert (!roots.isEmpty()); JGraphLayoutAlgorithm layout = new SugiyamaLayoutAlgorithm(); JGraphLayoutAlgorithm.applyLayout(graph, layout, roots.toArray(), null); // SugiyamaLayoutAlgorithm doesn't normalize its output, leading to a // cumulative bias for each round. We compensate for this by computing // the bounding rectangle and applying a corresponding negative // translation. Rectangle2D bounds = graph.getCellBounds(graph.getRoots()); GraphLayoutCache.translateViews( graphView.getCellViews(), -bounds.getX(), -bounds.getY()); graphView.update(graphView.getCellViews()); graph.clearSelection(); if (state != STATE_RUNNING) { graph.setVisible(true); } } private void waitForInput() { synchronized (stepVar) { try { switch (state) { case STATE_CRAWLING: case STATE_STEPPING: stepVar.wait(); break; case STATE_WALKING: stepVar.wait(1000); break; default: break; } } catch (InterruptedException ex) { } } } private VisualVertex makeVertex(Object obj) { VisualVertex vertex = objToVertexMap.get(obj); if (vertex == null) { vertex = new VisualVertex(obj); objToVertexMap.put(obj, vertex); graphModel.addVertex(vertex); } vertex.generationNumber = currentGenerationNumber; return vertex; } private VisualEdge makeEdge(VisualVertex v1, VisualVertex v2, String label) { VisualEdge edge = graphModel.getEdge(v1, v2); if (edge == null) { edge = new VisualEdge(label); graphModel.addEdge(v1, v2, edge); } else { // e.g. self-join if (!edge.toString().contains(label)) { edge.setLabel(edge.toString() + ", " + label); } } edge.generationNumber = currentGenerationNumber; return edge; } public void init() { graphModel = new ListenableDirectedGraph( new DefaultDirectedGraph( new VisualEdgeFactory())); AttributeMap defaultVertexAttributes = JGraphModelAdapter.createDefaultVertexAttributes(); GraphConstants.setBounds( defaultVertexAttributes, new Rectangle2D.Double(50, 50, 200, 30)); normalVertexAttributes = new AttributeMap(); GraphConstants.setBackground( defaultVertexAttributes, Color.GRAY); GraphConstants.setBackground( normalVertexAttributes, Color.GRAY); oldVertexAttributes = new AttributeMap(); GraphConstants.setBackground( oldVertexAttributes, Color.GREEN); finalVertexAttributes = new AttributeMap(); GraphConstants.setBackground( finalVertexAttributes, Color.BLUE); newVertexAttributes = new AttributeMap(); GraphConstants.setBackground( newVertexAttributes, Color.RED); graphAdapter = new JGraphModelAdapter( graphModel, defaultVertexAttributes, JGraphModelAdapter.createDefaultEdgeAttributes(graphModel)); graph = new JGraph(graphAdapter); scrollPane = new JScrollPane(graph); scrollPane.setPreferredSize(new Dimension(500, 500)); scrollPane.setColumnHeaderView(status); graph.setAutoscrolls(true); graphView = graph.getGraphLayoutCache(); getContentPane().add(scrollPane); frame.pack(); } private static class VisualVertex { int generationNumber; final RelNode rel; final String name; final Object obj; VisualVertex(Object obj) { this.obj = obj; if (obj instanceof RelNode) { rel = (RelNode) obj; name = rel.getId() + ":" + rel; } else { rel = null; name = obj.toString(); } } public String toString() { return name; } } private static class VisualEdge extends DefaultEdge { private String label; int generationNumber; VisualEdge( String label) { this.label = label; } public void setLabel(String label) { this.label = label; } public String toString() { return label; } } private static class VisualEdgeFactory implements EdgeFactory { public VisualEdge createEdge( VisualVertex sourceVertex, VisualVertex targetVertex) { return new VisualEdge(""); } } } // End FarragoPlanVisualizer.java ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrooteigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlannervizPluginFactory.javaeigenbase-farrago-0.9.0/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlannervizPluginFac0000444000175000017500000000603511173714170033733 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlannervizPluginFactory.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plannerviz; import net.sf.farrago.session.*; import org.eigenbase.util.*; import java.lang.reflect.*; import java.util.*; /** * FarragoPlannervizPluginFactory implements the * {@link FarragoSessionPersonalityFactory} interface by producing * a session personality which adds in the necessary listener for * visualizing planner events. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/plannerviz/src/net/sf/farrago/plannerviz/FarragoPlannervizPluginFactory.java#7 $ */ public class FarragoPlannervizPluginFactory implements FarragoSessionPersonalityFactory { // implement FarragoSessionPersonalityFactory public FarragoSessionPersonality newSessionPersonality( FarragoSession session, FarragoSessionPersonality defaultPersonality) { // create a delegating proxy, overriding only the methods // we're interested in return (FarragoSessionPersonality) Proxy.newProxyInstance( FarragoPlannervizPluginFactory.class.getClassLoader(), new Class[] { FarragoSessionPersonality.class, }, new PlannervizPersonality(defaultPersonality)); } public static class PlannervizPersonality extends DelegatingInvocationHandler { private final FarragoSessionPersonality defaultPersonality; PlannervizPersonality(FarragoSessionPersonality defaultPersonality) { this.defaultPersonality = defaultPersonality; } // implement DelegatingInvocationHandler protected Object getTarget() { return defaultPersonality; } // implement FarragoSessionPersonality public void definePlannerListeners(FarragoSessionPlanner planner) { defaultPersonality.definePlannerListeners(planner); planner.addListener( new FarragoPlanVisualizer()); } } } // End FarragoPlannervizPluginFactory.java eigenbase-farrago-0.9.0/examples/dmv/0000755000175000017500000000000011173714170017363 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/dmv/test.ref0000444000175000017500000001013311173714170021034 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/examples/dmv/test.ref#1 $ > -- This script exercises package org.eigenbase.dmv > -- (but it doesn't actually verify any output yet) > > create schema accounts; > > create table accounts.customers(customer_id int not null primary key); > > create table accounts.addresses(address_id int not null primary key); > > create view accounts.customer_addresses > as select * from accounts.customers, accounts.addresses; > > create schema car_rentals; > > create table car_rentals.cars(car_id int not null primary key); > > create table car_rentals.contracts(contract_id int not null primary key); > > create view car_rentals.customer_rentals as > select * from accounts.customers, car_rentals.contracts, car_rentals.cars; > > create schema lodging; > > create table lodging.hotels(hotel_id int not null primary key); > > create table lodging.cabins(cabin_id int not null primary key); > > create view lodging.locations as > select * from lodging.hotels > union all > select * from lodging.cabins; > > create view lodging.registrations as > select * from accounts.customers, lodging.locations; > > create schema billing; > > create view billing.events as > select * from car_rentals.customer_rentals, lodging.registrations; > > create view billing.all_addresses as > select * from accounts.addresses, lodging.locations; > > create schema dmv_test; > > create procedure dmv_test.dmv_render_graphviz( > foreign_server_name varchar(128), > lurql_filename varchar(1024), > transformation_filename varchar(1024), > dot_filename varchar(1024)) > language java > no sql > external name 'class net.sf.farrago.test.DmvTestUdr.renderGraphviz'; > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/schemaDependencies.lurql', > '${FARRAGO_HOME}/examples/dmv/schemaDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/schemaDependencies.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/schemaDependencies.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/objectDependenciesGrouped.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/objectDependencies.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/objectDependencies.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/schemaDependencies.lurql', > '${FARRAGO_HOME}/examples/dmv/viewsFloating.xml', > '${FARRAGO_HOME}/examples/dmv/results/viewsFloating.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/customersDownstream.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/customersDownstream.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/eventsUpstream.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/eventsUpstream.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/registrationsUpAndDownStream.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/registrationsUpAndDownStream.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/carRentalsOnly.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/carRentalsOnly.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/carRentalsPlusPeriphery.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', > '${FARRAGO_HOME}/examples/dmv/results/carRentalsPlusPeriphery.dot'); > > call dmv_test.dmv_render_graphviz( > null, > '${FARRAGO_HOME}/examples/dmv/carRentalsOnly.lurql', > '${FARRAGO_HOME}/examples/dmv/objectDependenciesReversed.xml', > '${FARRAGO_HOME}/examples/dmv/results/carRentalsReversed.dot'); > > !quit eigenbase-farrago-0.9.0/examples/dmv/schemaDependencies.lurql0000444000175000017500000000032111173714170024205 0ustar drazzibdrazzibselect * from class LocalSchema where name in ('ACCOUNTS', 'CAR_RENTALS', 'LODGING', 'BILLING') then ( follow composite forward destination class ColumnSet then ( follow origin end client ) ); eigenbase-farrago-0.9.0/examples/dmv/objectDependencies.xml0000444000175000017500000000042611173714170023662 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/dmv/carRentalsOnly.lurql0000444000175000017500000000025411173714170023403 0ustar drazzibdrazzibselect * from class LocalSchema where name = 'CAR_RENTALS' then ( follow composite forward destination class ColumnSet then ( follow origin end client ) ); eigenbase-farrago-0.9.0/examples/dmv/eventsUpstream.lurql0000444000175000017500000000044611173714170023473 0ustar drazzibdrazzibselect * from class ColumnSet where name='EVENTS' then ( recursively ( follow origin end client then ( follow destination end supplier destination class ColumnSet ) ) ) gather with parent then ( follow composite backward destination class LocalSchema ); eigenbase-farrago-0.9.0/examples/dmv/schemaDependencies.xml0000444000175000017500000000043011173714170023647 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/dmv/DmvTransformationRuleSet.dtd0000444000175000017500000000116711173714170025044 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/dmv/viewsFloating.xml0000444000175000017500000000056511173714170022732 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/dmv/carRentalsPlusPeriphery.lurql0000444000175000017500000000075511173714170025303 0ustar drazzibdrazzibselect * from class LocalSchema where name = 'CAR_RENTALS' then ( follow composite forward destination class ColumnSet then ( follow origin end client then ( follow destination end supplier destination class ColumnSet ) union follow origin end supplier then ( follow destination end client destination class ColumnSet ) ) gather with parent then ( follow composite backward destination class LocalSchema ) ); eigenbase-farrago-0.9.0/examples/dmv/test.sql0000444000175000017500000000755411173714170021074 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/examples/dmv/test.sql#1 $ -- This script exercises package org.eigenbase.dmv -- (but it doesn't actually verify any output yet) create schema accounts; create table accounts.customers(customer_id int not null primary key); create table accounts.addresses(address_id int not null primary key); create view accounts.customer_addresses as select * from accounts.customers, accounts.addresses; create schema car_rentals; create table car_rentals.cars(car_id int not null primary key); create table car_rentals.contracts(contract_id int not null primary key); create view car_rentals.customer_rentals as select * from accounts.customers, car_rentals.contracts, car_rentals.cars; create schema lodging; create table lodging.hotels(hotel_id int not null primary key); create table lodging.cabins(cabin_id int not null primary key); create view lodging.locations as select * from lodging.hotels union all select * from lodging.cabins; create view lodging.registrations as select * from accounts.customers, lodging.locations; create schema billing; create view billing.events as select * from car_rentals.customer_rentals, lodging.registrations; create view billing.all_addresses as select * from accounts.addresses, lodging.locations; create schema dmv_test; create procedure dmv_test.dmv_render_graphviz( foreign_server_name varchar(128), lurql_filename varchar(1024), transformation_filename varchar(1024), dot_filename varchar(1024)) language java no sql external name 'class net.sf.farrago.test.DmvTestUdr.renderGraphviz'; call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/schemaDependencies.lurql', '${FARRAGO_HOME}/examples/dmv/schemaDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/schemaDependencies.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/schemaDependencies.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/objectDependenciesGrouped.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/objectDependencies.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/objectDependencies.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/schemaDependencies.lurql', '${FARRAGO_HOME}/examples/dmv/viewsFloating.xml', '${FARRAGO_HOME}/examples/dmv/results/viewsFloating.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/customersDownstream.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/customersDownstream.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/eventsUpstream.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/eventsUpstream.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/registrationsUpAndDownStream.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/registrationsUpAndDownStream.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/carRentalsOnly.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/carRentalsOnly.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/carRentalsPlusPeriphery.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependencies.xml', '${FARRAGO_HOME}/examples/dmv/results/carRentalsPlusPeriphery.dot'); call dmv_test.dmv_render_graphviz( null, '${FARRAGO_HOME}/examples/dmv/carRentalsOnly.lurql', '${FARRAGO_HOME}/examples/dmv/objectDependenciesReversed.xml', '${FARRAGO_HOME}/examples/dmv/results/carRentalsReversed.dot'); eigenbase-farrago-0.9.0/examples/dmv/objectDependenciesReversed.xml0000444000175000017500000000053411173714170025362 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/dmv/expected/0000755000175000017500000000000011173714170021164 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/dmv/expected/objectDependenciesGrouped.dot0000444000175000017500000000265311173714170027003 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster15822478 { bgcolor=white; label="LocalSchema:ACCOUNTS"; 9527662[label="{LocalTable|CUSTOMERS}"]; 9681035[label="{LocalTable|ADDRESSES}"]; 3729784[label="{LocalView|CUSTOMER_ADDRESSES}"]; } subgraph cluster6802579 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 11003097[label="{LocalTable|CARS}"]; 10591844[label="{LocalTable|CONTRACTS}"]; 10868046[label="{LocalView|CUSTOMER_RENTALS}"]; } subgraph cluster22485284 { bgcolor=white; label="LocalSchema:LODGING"; 20171724[label="{LocalTable|HOTELS}"]; 25744969[label="{LocalTable|CABINS}"]; 11308250[label="{LocalView|LOCATIONS}"]; 5465232[label="{LocalView|REGISTRATIONS}"]; } subgraph cluster15678347 { bgcolor=white; label="LocalSchema:BILLING"; 3025756[label="{LocalView|EVENTS}"]; 18926352[label="{LocalView|ALL_ADDRESSES}"]; } 9527662->3729784[]; 9681035->3729784[]; 9527662->10868046[]; 11003097->10868046[]; 10591844->10868046[]; 20171724->11308250[]; 25744969->11308250[]; 9527662->5465232[]; 11308250->5465232[]; 10868046->3025756[]; 5465232->3025756[]; 9681035->18926352[]; 11308250->18926352[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/registrationsUpAndDownStream.dot0000444000175000017500000000151711173714170027527 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster1779545 { bgcolor=white; label="LocalSchema:ACCOUNTS"; 11818906[label="{LocalTable|CUSTOMERS}"]; } subgraph cluster31678629 { bgcolor=white; label="LocalSchema:LODGING"; 14561851[label="{LocalTable|HOTELS}"]; 28562547[label="{LocalTable|CABINS}"]; 21025824[label="{LocalView|LOCATIONS}"]; 19301003[label="{LocalView|REGISTRATIONS}"]; } subgraph cluster21266054 { bgcolor=white; label="LocalSchema:BILLING"; 30316875[label="{LocalView|EVENTS}"]; } 14561851->21025824[]; 28562547->21025824[]; 11818906->19301003[]; 21025824->19301003[]; 19301003->30316875[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/schemaDependencies.dot0000444000175000017500000000067211173714170025446 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] 28060855[label="{LocalSchema|ACCOUNTS}"]; 11254222[label="{LocalSchema|CAR_RENTALS}"]; 3376320[label="{LocalSchema|LODGING}"]; 5277309[label="{LocalSchema|BILLING}"]; 28060855->11254222[]; 28060855->3376320[]; 11254222->5277309[]; 3376320->5277309[]; 28060855->5277309[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/carRentalsOnly.dot0000444000175000017500000000066211173714170024636 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster9556866 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 30749303[label="{LocalTable|CARS}"]; 31729842[label="{LocalTable|CONTRACTS}"]; 2878521[label="{LocalView|CUSTOMER_RENTALS}"]; } 30749303->2878521[]; 31729842->2878521[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/eventsUpstream.dot0000444000175000017500000000225311173714170024721 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster21133685 { bgcolor=white; label="LocalSchema:ACCOUNTS"; 20185179[label="{LocalTable|CUSTOMERS}"]; } subgraph cluster17005019 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 20268676[label="{LocalTable|CARS}"]; 11058995[label="{LocalTable|CONTRACTS}"]; 10536243[label="{LocalView|CUSTOMER_RENTALS}"]; } subgraph cluster15907973 { bgcolor=white; label="LocalSchema:LODGING"; 3594724[label="{LocalTable|HOTELS}"]; 18561038[label="{LocalTable|CABINS}"]; 33378807[label="{LocalView|LOCATIONS}"]; 1062740[label="{LocalView|REGISTRATIONS}"]; } subgraph cluster10521767 { bgcolor=white; label="LocalSchema:BILLING"; 7495067[label="{LocalView|EVENTS}"]; } 20185179->10536243[]; 20268676->10536243[]; 11058995->10536243[]; 3594724->33378807[]; 18561038->33378807[]; 20185179->1062740[]; 33378807->1062740[]; 10536243->7495067[]; 1062740->7495067[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/customersDownstream.dot0000444000175000017500000000161111173714170025761 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster22678319 { bgcolor=white; label="LocalSchema:ACCOUNTS"; 9720825[label="{LocalTable|CUSTOMERS}"]; 1378281[label="{LocalView|CUSTOMER_ADDRESSES}"]; } subgraph cluster12216475 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 2729163[label="{LocalView|CUSTOMER_RENTALS}"]; } subgraph cluster149512 { bgcolor=white; label="LocalSchema:LODGING"; 29825469[label="{LocalView|REGISTRATIONS}"]; } subgraph cluster7003845 { bgcolor=white; label="LocalSchema:BILLING"; 4689432[label="{LocalView|EVENTS}"]; } 9720825->1378281[]; 9720825->2729163[]; 9720825->29825469[]; 2729163->4689432[]; 29825469->4689432[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/carRentalsReversed.dot0000444000175000017500000000066311173714170025475 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster9362324 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 15859973[label="{LocalTable|CARS}"]; 2163516[label="{LocalTable|CONTRACTS}"]; 22775390[label="{LocalView|CUSTOMER_RENTALS}"]; } 22775390->15859973[]; 22775390->2163516[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/viewsFloating.dot0000444000175000017500000000254611173714170024522 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster4572701 { bgcolor=white; label="LocalSchema:ACCOUNTS"; 13746179[label="{LocalTable|CUSTOMERS}"]; 9771755[label="{LocalTable|ADDRESSES}"]; } 18502456[label="{LocalView|CUSTOMER_ADDRESSES}"]; subgraph cluster21858368 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 19677226[label="{LocalTable|CARS}"]; 2668086[label="{LocalTable|CONTRACTS}"]; } 13811037[label="{LocalView|CUSTOMER_RENTALS}"]; subgraph cluster26107266 { bgcolor=white; label="LocalSchema:LODGING"; 27077013[label="{LocalTable|HOTELS}"]; 18158797[label="{LocalTable|CABINS}"]; } 17345432[label="{LocalView|LOCATIONS}"]; 3777634[label="{LocalView|REGISTRATIONS}"]; 5712737[label="{LocalSchema|BILLING}"]; 14748992[label="{LocalView|EVENTS}"]; 19729454[label="{LocalView|ALL_ADDRESSES}"]; 13746179->18502456[]; 9771755->18502456[]; 13746179->13811037[]; 19677226->13811037[]; 2668086->13811037[]; 27077013->17345432[]; 18158797->17345432[]; 13746179->3777634[]; 17345432->3777634[]; 13811037->14748992[]; 3777634->14748992[]; 9771755->19729454[]; 17345432->19729454[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/carRentalsPlusPeriphery.dot0000444000175000017500000000140511173714170026524 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] subgraph cluster12072347 { bgcolor=white; label="LocalSchema:ACCOUNTS"; 29853907[label="{LocalTable|CUSTOMERS}"]; } subgraph cluster15196112 { bgcolor=white; label="LocalSchema:CAR_RENTALS"; 18284893[label="{LocalTable|CARS}"]; 22717992[label="{LocalTable|CONTRACTS}"]; 5410519[label="{LocalView|CUSTOMER_RENTALS}"]; } subgraph cluster2082417 { bgcolor=white; label="LocalSchema:BILLING"; 1925978[label="{LocalView|EVENTS}"]; } 29853907->5410519[]; 18284893->5410519[]; 22717992->5410519[]; 5410519->1925978[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/objectDependencies.dot0000444000175000017500000000177511173714170025461 0ustar drazzibdrazzibdigraph G { graph [bgcolor=gray] node [shape=record, style=filled, fillcolor=white, fontsize=10.0] edge [fontsize=10.0] 28830939[label="{LocalTable|CUSTOMERS}"]; 2049991[label="{LocalTable|ADDRESSES}"]; 27351783[label="{LocalView|CUSTOMER_ADDRESSES}"]; 5709462[label="{LocalTable|CARS}"]; 26807578[label="{LocalTable|CONTRACTS}"]; 19613595[label="{LocalView|CUSTOMER_RENTALS}"]; 6956340[label="{LocalTable|HOTELS}"]; 11566659[label="{LocalTable|CABINS}"]; 20021468[label="{LocalView|LOCATIONS}"]; 16975564[label="{LocalView|REGISTRATIONS}"]; 28532345[label="{LocalView|EVENTS}"]; 16744380[label="{LocalView|ALL_ADDRESSES}"]; 28830939->27351783[]; 2049991->27351783[]; 28830939->19613595[]; 5709462->19613595[]; 26807578->19613595[]; 6956340->20021468[]; 11566659->20021468[]; 28830939->16975564[]; 20021468->16975564[]; 19613595->28532345[]; 16975564->28532345[]; 2049991->16744380[]; 20021468->16744380[]; } eigenbase-farrago-0.9.0/examples/dmv/expected/README0000444000175000017500000000050011173714170022035 0ustar drazzibdrazzibThis directory contains pre-generated .dot output for the example visualizations. Compare with the actual results in sibling directory "results" after running the visualizations yourself. View .dot files with a command like dot -Tpng eventsUpstream.dot | display (Requires installation of Graphviz and ImageMagick.) eigenbase-farrago-0.9.0/examples/dmv/registrationsUpAndDownStream.lurql0000444000175000017500000000071111173714170026272 0ustar drazzibdrazzibselect * from class ColumnSet where name='REGISTRATIONS' then ( recursively ( follow origin end supplier then ( follow destination end client destination class ColumnSet ) ) union recursively ( follow origin end client then ( follow destination end supplier destination class ColumnSet ) ) ) gather with parent then ( follow composite backward destination class LocalSchema ); eigenbase-farrago-0.9.0/examples/dmv/objectDependencies.lurql0000444000175000017500000000033611173714170024221 0ustar drazzibdrazzibselect o, d from class LocalSchema where name in ('ACCOUNTS', 'CAR_RENTALS', 'LODGING', 'BILLING') then ( follow composite forward destination class ColumnSet as o then ( follow origin end client as d ) ); eigenbase-farrago-0.9.0/examples/dmv/customersDownstream.lurql0000444000175000017500000000043611173714170024535 0ustar drazzibdrazzibselect * from class ColumnSet where name='CUSTOMERS' then ( recursively ( follow origin end supplier then ( follow destination end client destination class ColumnSet ) ) then ( follow composite backward destination class LocalSchema ) ); eigenbase-farrago-0.9.0/examples/dmv/README0000444000175000017500000000055211173714170020243 0ustar drazzibdrazzibThis directory contains - test.sql: creates an example schema and then runs a number of example visualizations; results are written into subdirectory named "results" in .dot form - *.lurql: LURQL queries used by example visualizations - *.xml: transformation rule files used by example visualizations For more information, see farrago/doc/dmv/index.html eigenbase-farrago-0.9.0/examples/dmv/results/0000755000175000017500000000000011173714170021064 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/dmv/results/README0000444000175000017500000000043511173714170021744 0ustar drazzibdrazzibThis directory receives the actual .dot output of running the example visualizations. Compare with the expected results in sibling directory "expected". View .dot files with a command like dot -Tpng eventsUpstream.dot | display (Requires installation of Graphviz and ImageMagick.) eigenbase-farrago-0.9.0/examples/miniplan/0000755000175000017500000000000011173714170020404 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/miniplan/build.xml0000444000175000017500000000464611173714170022235 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/miniplan/src/0000755000175000017500000000000011173714170021173 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/miniplan/src/net/0000755000175000017500000000000011173714170021761 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/0000755000175000017500000000000011173714170022371 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/farrago/0000755000175000017500000000000011173714170024012 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/farrago/miniplan/0000755000175000017500000000000011173714170025621 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrooteigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/farrago/miniplan/PushAggThroughUnionAllRule.javaeigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/farrago/miniplan/PushAggThroughUnionAllRule.jav0000444000175000017500000001137711173714170033523 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/miniplan/src/net/sf/farrago/miniplan/PushAggThroughUnionAllRule.java#5 $ // Farrago is an extensible data management system. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.miniplan; import org.eigenbase.rel.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.rel.metadata.*; import java.util.*; /** * PushAggThroughUnionAllRule implements the rule for pushing an * {@link AggregateRel} past a non-distinct {@link UnionRel}. * *

* * If you modify this class, please update the * corresponding wiki page as well. * * @author John Sichi * @version $Id: //open/dev/farrago/examples/miniplan/src/net/sf/farrago/miniplan/PushAggThroughUnionAllRule.java#5 $ */ public class PushAggThroughUnionAllRule extends RelOptRule { public static final PushAggThroughUnionAllRule instance = new PushAggThroughUnionAllRule(); public PushAggThroughUnionAllRule() { super( new RelOptRuleOperand( AggregateRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand(UnionRel.class, RelOptRule.ANY) })); } public void onMatch(RelOptRuleCall call) { AggregateRel aggRel = (AggregateRel) call.rels[0]; UnionRel unionRel = (UnionRel) call.rels[1]; if (unionRel.isDistinct()) { // This transformation is only valid for UNION ALL. // Consider t1(i) with rows (5), (5) and t2(i) with // rows (5), (10), and the query // select sum(i) from (select i from t1) union (select i from t2). // The correct answer is 15. If we apply the transformation, // we get // select sum(i) from // (select sum(i) as i from t1) union (select sum(i) as i from t2) // which yields 25 (incorrect). return; } // NOTE jvs 24-Aug-2008: There's a bug in this code. When // you find it, please don't fix it! Finding it is an exercise // in http://wiki.eigenbase.org/pub/HowToWriteAnOptimizer, // so we want it to stay around. RelNode [] unionInputs = unionRel.getInputs(); int nUnionInputs = unionInputs.length; RelNode [] newUnionInputs = new RelNode[nUnionInputs]; RelOptCluster cluster = unionRel.getCluster(); BitSet groupByKeyMask = new BitSet(); for (int i = 0; i < aggRel.getGroupCount(); i++) { groupByKeyMask.set(i); } boolean anyTransformed = false; // create corresponding aggs on top of each union child for (int i = 0; i < nUnionInputs; i++) { boolean alreadyUnique = RelMdUtil.areColumnsDefinitelyUnique( unionInputs[i], groupByKeyMask); if (alreadyUnique) { newUnionInputs[i] = unionInputs[i]; } else { anyTransformed = true; newUnionInputs[i] = new AggregateRel( cluster, unionInputs[i], aggRel.getGroupCount(), aggRel.getAggCallList()); } } if (!anyTransformed) { // none of the children could benefit from the pushdown, // so bail out (preventing the infinite loop to which most // planners would succumb) return; } // create a new union whose children are the aggs created above UnionRel newUnionRel = new UnionRel(cluster, newUnionInputs, true); AggregateRel newTopAggRel = new AggregateRel( cluster, newUnionRel, aggRel.getGroupCount(), aggRel.getAggCallList()); call.transformTo(newTopAggRel); } } // End PushAggThroughUnionAllRule.java ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrooteigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/farrago/miniplan/FarragoMiniplanPersonalityFactory.javaeigenbase-farrago-0.9.0/examples/miniplan/src/net/sf/farrago/miniplan/FarragoMiniplanPersonalityFact0000444000175000017500000001406011173714170033644 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/miniplan/src/net/sf/farrago/miniplan/FarragoMiniplanPersonalityFactory.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.miniplan; import net.sf.farrago.fennel.rel.*; import org.eigenbase.relopt.volcano.*; import com.lucidera.opt.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.query.*; import net.sf.farrago.db.*; import net.sf.farrago.session.*; import net.sf.farrago.defimpl.*; import org.eigenbase.oj.rel.*; import org.eigenbase.rel.*; import org.eigenbase.rel.rules.*; import org.eigenbase.relopt.*; import org.eigenbase.relopt.hep.*; import java.util.*; /** * FarragoMiniplanPersonalityFactory implements the {@link * FarragoSessionPersonalityFactory} interface by plugging in * a "mini" planner meant only for tutorial purposes. * *

* * If you modify this class, please update the * corresponding wiki page as well. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/miniplan/src/net/sf/farrago/miniplan/FarragoMiniplanPersonalityFactory.java#7 $ */ public class FarragoMiniplanPersonalityFactory implements FarragoSessionPersonalityFactory { //~ Methods ---------------------------------------------------------------- // implement FarragoSessionPersonalityFactory public FarragoSessionPersonality newSessionPersonality( FarragoSession session, FarragoSessionPersonality defaultPersonality) { return new FarragoMiniplanSessionPersonality( (FarragoDbSession) session); } private static void addMiniplannerRules(FarragoSessionPlanner planner) { planner.addRule(PushProjectPastSetOpRule.instance); planner.addRule(LhxAggRule.instance); planner.addRule(RemoveTrivialProjectRule.instance); planner.addRule(FennelUnionRule.instance); planner.addRule(FennelReshapeRule.instance); planner.addRule(PushAggThroughUnionAllRule.instance); FennelToIteratorConverter.register(planner); IteratorToFennelConverter.register(planner); } private static HepProgram createMiniplannerHepProgram( Collection medPluginRules) { HepProgramBuilder builder = new HepProgramBuilder(); builder.addGroupBegin(); builder.addRuleInstance(RemoveTrivialProjectRule.instance); builder.addRuleInstance(PushProjectPastSetOpRule.instance); builder.addRuleInstance(MergeProjectRule.instance); builder.addGroupEnd(); builder.addRuleInstance(PushAggThroughUnionAllRule.instance); builder.addRuleCollection(medPluginRules); builder.addRuleInstance(RemoveTrivialProjectRule.instance); builder.addRuleInstance(LhxAggRule.instance); builder.addRuleInstance(FennelReshapeRule.instance); builder.addRuleInstance(FennelUnionRule.instance); builder.addConverters(true); return builder.createProgram(); } //~ Inner Classes ---------------------------------------------------------- private static class FarragoMiniplanSessionPersonality extends FarragoDefaultSessionPersonality { private static final String MINIPLAN_VOLCANO = "volcano"; protected FarragoMiniplanSessionPersonality(FarragoDbSession session) { super(session); paramValidator.registerBoolParam(MINIPLAN_VOLCANO, false); } // implement FarragoSessionPersonality public void loadDefaultSessionVariables( FarragoSessionVariables variables) { super.loadDefaultSessionVariables(variables); variables.setDefault(MINIPLAN_VOLCANO, "false"); } // implement FarragoSessionPersonality public FarragoSessionPlanner newPlanner( FarragoSessionPreparingStmt stmt, boolean init) { boolean useVolcano = stmt.getSession().getSessionVariables().getBoolean( MINIPLAN_VOLCANO); if (useVolcano) { FarragoVolcanoMiniplanner planner = new FarragoVolcanoMiniplanner(stmt); if (init) { planner.init(); } return planner; } else { Collection medPluginRules = new LinkedHashSet(); HepProgram program = createMiniplannerHepProgram( medPluginRules); FarragoDefaultHeuristicPlanner planner = new FarragoDefaultHeuristicPlanner( program, stmt, medPluginRules); addMiniplannerRules(planner); return planner; } } } private static class FarragoVolcanoMiniplanner extends FarragoDefaultPlanner { public FarragoVolcanoMiniplanner(FarragoSessionPreparingStmt stmt) { super(stmt); } public void init() { addMiniplannerRules(this); } } } // End FarragoMiniplanPersonalityFactory.java eigenbase-farrago-0.9.0/examples/miniplan/unitsql/0000755000175000017500000000000011173714170022103 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/0000755000175000017500000000000011173714170017363 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/catalog/0000755000175000017500000000000011173714170020775 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/catalog/xmi/0000755000175000017500000000000011173714170021572 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/catalog/xmi/RandomNumberGeneratorModel.uml0000444000175000017500000012411111173714170027530 0ustar drazzibdrazzib 0.19.7 Netbeans XMI Writer 1.0 <p> </p> Package Attribute DataType Class Class Class Dependency Dependency Dependency Class Class Dependency <p>FEME is a placeholder for the top-level Farrago package which contains CWM, FEM, and all plugin extension models.</p> FEM Association RandomNumberGenerator serializedFile : String initialSeed [0..1] : Long ModelElement sourcePortFig="Fig0" destPortFig="Fig1" sourceFigNode="Fig0" destFigNode="Fig1" eigenbase-farrago-0.9.0/examples/rng/build.xml0000444000175000017500000000740011173714170021203 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/examples/rng/src/0000755000175000017500000000000011173714170020152 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/0000755000175000017500000000000011173714170020740 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/0000755000175000017500000000000011173714170021350 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/0000755000175000017500000000000011173714170022771 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rngmodel/0000755000175000017500000000000011173714170024600 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rngmodel/package.html0000444000175000017500000000107011173714170027055 0ustar drazzibdrazzib Package net.sf.farrago.rngmodel Defines the metamodel for the RNG plugin example.
Revision $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rngmodel/package.html#3 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John Pham
eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/0000755000175000017500000000000011173714170023557 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngNextRandomIntOperator.java0000444000175000017500000000760711173714170032651 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngNextRandomIntOperator.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import org.eigenbase.sql.*; import org.eigenbase.sql.parser.*; import org.eigenbase.sql.type.*; import org.eigenbase.sql.validate.*; import org.eigenbase.util.*; import net.sf.farrago.query.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.rngmodel.rngschema.RngRandomNumberGenerator; /** * FarragoRngNextRandomIntOperator defines the SqlOperator for the * NEXT_RANDOM_INT pseudo-function. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngNextRandomIntOperator.java#11 $ */ public class FarragoRngNextRandomIntOperator extends SqlFunction { public FarragoRngNextRandomIntOperator() { super( "NEXT_RANDOM_INT", SqlKind.Other, SqlTypeStrategies.rtiInteger, null, new FamilyOperandTypeChecker( SqlTypeFamily.INTEGER, SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER), SqlFunctionCategory.System); } // override SqlOperator public void validateCall( SqlCall call, SqlValidator validator, SqlValidatorScope scope, SqlValidatorScope operandScope) { super.validateCall(call, validator, scope, operandScope); // TODO jvs 18-Apr-2005: make this an official part of session-level // interface FarragoPreparingStmt preparingStmt = (FarragoPreparingStmt) validator.getCatalogReader(); // This is kind of silly...we already had the rng reference // during parsing, but then we lost it. SqlParser sqlParser = new SqlParser( ((SqlLiteral) call.operands[1]).getStringValue()); SqlIdentifier id; try { id = (SqlIdentifier) sqlParser.parseExpression(); } catch (Throwable ex) { throw Util.newInternal(ex); } RngRandomNumberGenerator rng = preparingStmt.getStmtValidator().findSchemaObject( id, RngRandomNumberGenerator.class); // TODO jvs 27-Aug-2005: make this USAGE instead preparingStmt.addDependency(rng, PrivilegedActionEnum.REFERENCES); } // override SqlOperator public void unparse( SqlWriter writer, SqlNode [] operands, int leftPrec, int rightPrec) { final SqlWriter.Frame frame = writer.startFunCall(getName()); SqlLiteral ceiling = (SqlLiteral) operands[0]; if (ceiling.intValue(true) == -1) { writer.sep("UNBOUNDED"); } else { writer.sep("CEILING"); ceiling.unparse(writer, leftPrec, rightPrec); } writer.sep("FROM"); SqlLiteral id = (SqlLiteral) operands[1]; writer.literal(id.getStringValue()); writer.endFunCall(frame); } } // End FarragoRngNextRandomIntOperator.java eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/package.html0000444000175000017500000000107011173714170026034 0ustar drazzibdrazzib Package net.sf.farrago.rng Contains class definitions for the Farrago RNG example.
Revision $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/package.html#6 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngImplementorTable.java0000444000175000017500000000516111173714170031637 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngImplementorTable.java#5 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import net.sf.farrago.ojrex.*; import java.lang.reflect.*; import org.eigenbase.sql.fun.*; import org.eigenbase.util.*; /** * FarragoRngImplementorTable extends {@link FarragoOJRexImplementorTable} * with code generation for the NEXT_RANDOM_INT operator. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngImplementorTable.java#5 $ */ public class FarragoRngImplementorTable extends FarragoOJRexImplementorTable { private static FarragoRngImplementorTable instance; private FarragoRngImplementorTable(SqlStdOperatorTable opTab) { super(opTab); Method method; try { method = FarragoRngUDR.class.getMethod( "rng_next_int_internal", new Class [] { Integer.TYPE, String.class, String.class }); } catch (Exception ex) { throw Util.newInternal(ex); } registerOperator( FarragoRngOperatorTable.rngInstance().nextRandomInt, new FarragoOJRexStaticMethodImplementor(method, false, null)); } /** * Retrieves the singleton, creating it if necessary. * * @return singleton with RNG-specific type */ public static synchronized FarragoRngImplementorTable rngInstance() { if (instance == null) { instance = new FarragoRngImplementorTable( FarragoRngOperatorTable.rngInstance()); } return instance; } } // End FarragoRngImplementorTable.java eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/parserimpl/0000755000175000017500000000000011173714170025735 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/parserimpl/package.html0000444000175000017500000000134311173714170030215 0ustar drazzibdrazzib Package net.sf.farrago.rng.parserimpl Contains generated parser code for the Farrago RNG example. This package must NOT contain any non-generated classes, because the buildfile "clean" target automatically deletes everything in this package.
Revision $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/parserimpl/package.html#6 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngPluginFactory.java0000444000175000017500000001304011173714170031155 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngPluginFactory.java#9 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import net.sf.farrago.session.*; import net.sf.farrago.rng.resource.*; import net.sf.farrago.ddl.DdlHandler; import org.eigenbase.util.*; import org.eigenbase.resource.*; import org.eigenbase.resgen.*; import org.eigenbase.sql.*; import org.eigenbase.oj.rex.*; import java.lang.reflect.*; import java.util.*; /** * FarragoRngPluginFactory implements the * {@link FarragoSessionPersonalityFactory} interface by producing * session personality instances capable of understanding RNG DDL statements. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngPluginFactory.java#9 $ */ public class FarragoRngPluginFactory implements FarragoSessionPersonalityFactory, FarragoSessionModelExtensionFactory { public static final FarragoRngResource res; static { // REVIEW jvs 12-Apr-2005: FarragoRngResource.instance() has // problems loading the bundle from the jar. Find out why; // I think it has to do with ResourceBundle.getBundle not // knowing what to do when called from a static method. try { res = new FarragoRngResource(); } catch (Throwable ex) { throw Util.newInternal(ex); } } // implement FarragoSessionPersonalityFactory public FarragoSessionPersonality newSessionPersonality( FarragoSession session, FarragoSessionPersonality defaultPersonality) { // create a delegating proxy, overriding only the methods // we're interested in return (FarragoSessionPersonality) Proxy.newProxyInstance( FarragoRngPluginFactory.class.getClassLoader(), new Class[] { FarragoSessionPersonality.class, }, new RngPersonality(defaultPersonality)); } // implement FarragoSessionModelExtensionFactory public FarragoSessionModelExtension newModelExtension() { return new RngModelExtension(); } public static class RngPersonality extends DelegatingInvocationHandler { private final FarragoSessionPersonality defaultPersonality; RngPersonality(FarragoSessionPersonality defaultPersonality) { this.defaultPersonality = defaultPersonality; } // implement DelegatingInvocationHandler protected Object getTarget() { return defaultPersonality; } // implement FarragoSessionPersonality public FarragoSessionParser newParser(FarragoSession session) { return new FarragoRngParser(); } // implement FarragoSessionPersonality public SqlOperatorTable getSqlOperatorTable( FarragoSessionPreparingStmt preparingStmt) { return FarragoRngOperatorTable.rngInstance(); } // implement FarragoSessionPersonality public OJRexImplementorTable getOJRexImplementorTable( FarragoSessionPreparingStmt preparingStmt) { return FarragoRngImplementorTable.rngInstance(); } // implement FarragoSessionPersonality public boolean supportsFeature(ResourceDefinition feature) { // We disable SELECT DISTINCT in this personality just // so we can test the ability to selectively disable features // within specific personalities. if (feature == EigenbaseResource.instance().SQLFeature_E051_01) { return false; } return defaultPersonality.supportsFeature(feature); } // NOTE: we don't specify defineDdlHandlers here to avoid // duplication with RngModelExtension below. } public static class RngModelExtension implements FarragoSessionModelExtension { // implement FarragoSessionModelExtension public void defineDdlHandlers( FarragoSessionDdlValidator ddlValidator, List handlerList) { handlerList.add( new FarragoRngDdlHandler(ddlValidator)); } // implement FarragoSessionModelExtension public void defineResourceBundles( List bundleList) { bundleList.add(res); } // implement FarragoSessionModelExtension public void definePrivileges( FarragoSessionPrivilegeMap map) { // TODO: invent a custom rng privilege } } } // End FarragoRngPluginFactory.java eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngOperatorTable.java0000444000175000017500000000435511173714170031143 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngOperatorTable.java#6 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import org.eigenbase.sql.fun.*; /** * FarragoRngOperatorTable extends {@link SqlStdOperatorTable} with * the NEXT_RANDOM_INT operator provided by the RNG plugin. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngOperatorTable.java#6 $ */ public class FarragoRngOperatorTable extends SqlStdOperatorTable { private static FarragoRngOperatorTable instance; public final FarragoRngNextRandomIntOperator nextRandomInt = new FarragoRngNextRandomIntOperator(); /** * Retrieves the singleton, creating it if necessary. * * @return singleton with RNG-specific type */ public static synchronized FarragoRngOperatorTable rngInstance() { if (instance == null) { instance = new FarragoRngOperatorTable(); instance.init(); } return instance; } /** * Returns the {@link org.eigenbase.util.Glossary#SingletonPattern * singleton} instance, creating it if necessary. * * @return singleton with generic type */ public static SqlStdOperatorTable instance() { return rngInstance(); } } // End FarragoRngOperatorTable.java eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngParser.java0000444000175000017500000000312311173714170027624 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngParser.java#6 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import net.sf.farrago.parser.*; import net.sf.farrago.rng.parserimpl.*; import java.io.*; /** * FarragoRngParser is the public wrapper for the JavaCC-generated * RngParser. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngParser.java#6 $ */ public class FarragoRngParser extends FarragoAbstractParser { // implement FarragoAbstractParser protected FarragoAbstractParserImpl newParserImpl(Reader reader) { return new RngParser(reader); } } // End FarragoRngParser.java eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/RngParser.jj0000444000175000017500000001735311173714170026016 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/RngParser.jj#24 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ options { STATIC = false; UNICODE_INPUT = true; IGNORE_CASE = true; } PARSER_BEGIN(RngParser) package net.sf.farrago.rng.parserimpl; import net.sf.farrago.catalog.*; import net.sf.farrago.ddl.*; import net.sf.farrago.session.*; import net.sf.farrago.parser.*; import net.sf.farrago.util.*; import org.eigenbase.util.*; import org.eigenbase.util14.DateTimeUtil; import java.math.*; import java.util.*; import javax.jmi.reflect.*; import java.sql.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.rngmodel.*; import net.sf.farrago.rngmodel.rngschema.*; import org.eigenbase.reltype.*; import org.eigenbase.sql.*; import org.eigenbase.sql.fun.*; import org.eigenbase.sql.parser.*; import org.eigenbase.sql.type.*; import org.eigenbase.resource.*; import net.sf.farrago.resource.*; import net.sf.farrago.query.*; import net.sf.farrago.cwm.*; import net.sf.farrago.cwm.datatypes.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.cwm.relational.enumerations.*; import net.sf.farrago.cwm.keysindexes.*; import net.sf.farrago.cwm.behavioral.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.rng.*; /** * Farrago parser implementation extended with RNG syntax. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/RngParser.jj#24 $ */ public class RngParser extends FarragoAbstractParserImpl { private static Metadata metadata; public SqlParserPos getCurrentPosition() { return new SqlParserPos( token.beginLine, token.beginColumn); } public SqlParseException normalizeException(Throwable ex) { try { if (ex instanceof ParseException) { ex = cleanupParseException((ParseException) ex); } return convertException(ex); } catch (ParseException e) { throw new AssertionError(e); } } public Metadata getMetadata() { synchronized (RngParser.class) { if (metadata == null) { metadata = new MetadataImpl( new RngParser(new java.io.StringReader(""))); } return metadata; } } // implement SqlAbstractParserImpl public void setTabSize(int tabSize) { jj_input_stream.setTabSize(tabSize); } RngmodelPackage getRngModelPackage() { return FarragoRngUDR.getRngModelPackage(getRepos()); } } PARSER_END(RngParser) /***************************************** * Syntactical Descriptions * *****************************************/ /** * Allows parser to be extended with new types of table references. The * default implementation of this production is empty. */ SqlNode ExtendedTableRef() : { } { UnusedExtension() { return null; } } /** * Allows an OVER clause following a table expression as an extension to * standard SQL syntax. The default implementation of this production is empty. */ SqlNode TableOverOpt() : { } { { return null; } } /* * Parses dialect-specific keywords immediately following the SELECT keyword. */ void SqlSelectKeywords(List keywords) : {} { E() } /* * Parses dialect-specific keywords immediately following the INSERT keyword. */ void SqlInsertKeywords(List keywords) : {} { E() } String NonReservedKeyWord() : { String kw; } { ( kw = CommonNonReservedKeyWord() { return kw; } | kw = DdlNonReservedKeyWord() { return kw; } | kw = RngNonReservedKeyWord() { return kw; } ) } String RngNonReservedKeyWord() : { } { ( | ) { return getToken(0).image.toUpperCase(); } } CwmModelElement ExtensionModelSchemaObjDefinition() : { RngRandomNumberGenerator rng; SqlIdentifier qualifiedName; String externalLocation; long seed; } { { rng = getRngModelPackage().getRngschema() .getRngRandomNumberGenerator().createRngRandomNumberGenerator(); } qualifiedName = CompoundIdentifier3() { farragoParser.getDdlValidator().setSchemaObjectName( rng, qualifiedName); } externalLocation = QuotedString() { rng.setSerializedFile(externalLocation); } [ seed = UnsignedValue() { rng.setInitialSeed(new Long(seed)); } ] { return rng; } } long UnsignedValue() : { Token t; } { t = { try { return Long.parseLong(t.image); } catch (NumberFormatException ex) { throw generateParseException(); } } } CwmModelElement ExtensionModelDefinition() : { } { ( LOOKAHEAD({false}) ) { return null; } } CwmModelElement ExtensionModelDrop() : { SqlIdentifier qualifiedName; RngRandomNumberGenerator rng; } { qualifiedName = CompoundIdentifier3() { rng = farragoParser.getStmtValidator().findSchemaObject( qualifiedName, RngRandomNumberGenerator.class); } CascadeOption() { return rng; } } DdlStmt ExtensionModelAlter() : { } { ( LOOKAHEAD({false}) ) { return null; } } SqlNode ExtendedBuiltinFunctionCall() : { SqlIdentifier id; long longCeiling; int ceiling = -1; RngRandomNumberGenerator rng; } { ( longCeiling = UnsignedValue() { ceiling = (int) longCeiling; } | ) id = CompoundIdentifier3() { rng = farragoParser.getStmtValidator().findSchemaObject( id, RngRandomNumberGenerator.class); return FarragoRngOperatorTable.rngInstance().nextRandomInt.createCall( getPos(), SqlLiteral.createExactNumeric( Integer.toString(ceiling), getPos()), SqlLiteral.createCharString( FarragoCatalogUtil.getQualifiedName(rng).toString(), getPos()), SqlLiteral.createCharString( FarragoProperties.instance().expandProperties( rng.getSerializedFile()), getPos())); } } TOKEN : { < NEXT_RANDOM_INT: "NEXT_RANDOM_INT" > | < RNG: "RNG" > | < SEED: "SEED" > } /* * Parse Floor/Ceil function parameters */ SqlNode FloorCeilOptions( SqlParserPos pos, boolean floorFlag) : { SqlNode node; } { node = StandardFloorCeilOptions( pos, floorFlag) { return node; } } // End RngParser.jj eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/resource/0000755000175000017500000000000011173714170025406 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/resource/package.html0000444000175000017500000000111511173714170027663 0ustar drazzibdrazzib Package net.sf.farrago.rng.resource Contains resource definitions for the Farrago RNG example.
Revision $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/resource/package.html#5 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/resource/FarragoRngResource.xml0000444000175000017500000000342711173714170031674 0ustar drazzibdrazzib Failed to create serialization file {0} for {1} random number generator eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngUDR.java0000444000175000017500000001337511173714170027034 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngUDR.java#14 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import java.sql.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.rngmodel.*; import net.sf.farrago.rngmodel.rngschema.*; import net.sf.farrago.jdbc.FarragoJdbcUtil; import net.sf.farrago.jdbc.engine.*; import net.sf.farrago.catalog.*; import net.sf.farrago.util.*; import net.sf.farrago.trace.*; import net.sf.farrago.session.*; import java.io.*; import java.util.*; import java.util.logging.*; import javax.jmi.reflect.*; import org.eigenbase.sql.*; import org.eigenbase.sql.parser.*; import org.eigenbase.util.*; /** * FarragoRngUDR contains implementations for the user-defined routine * portion of the RNG plugin example. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngUDR.java#14 $ */ public abstract class FarragoRngUDR { private static final Logger tracer = FarragoTrace.getClassTracer(FarragoRngUDR.class); /** * Generates the next pseudo-random integer from a particular RNG. * * @param rngName name of the RNG (possibly qualified) * * @param n upper limit on generated nonnegative integer, or -1 for * unlimited (including negative) */ public static int rng_next_int( String rngName, int n) throws SQLException { Connection conn = DriverManager.getConnection( "jdbc:default:connection"); FarragoSession session = FarragoJdbcRoutineDriver.getSessionForConnection(conn); FarragoSessionStmtValidator stmtValidator = session.newStmtValidator(); FarragoReposTxnContext txn = null; try { SqlParser sqlParser = new SqlParser(rngName); SqlIdentifier rngId = (SqlIdentifier) sqlParser.parseExpression(); txn = session.getRepos().newTxnContext(true); txn.beginReadTxn(); RngRandomNumberGenerator rng = stmtValidator.findSchemaObject( rngId, RngRandomNumberGenerator.class); return rng_next_int_internal(n, rngName, getFilename(rng)); } catch (Throwable ex) { throw FarragoJdbcUtil.newSqlException(ex, tracer); } finally { if (txn != null) { txn.commit(); } } // NOTE jvs 7-Apr-2005: no need for cleanup; default connection // is cleaned up automatically. } /** * Generates the next pseudo-random integer from a particular RNG. * * @param n upper limit on generated nonnegative integer, or -1 for * unlimited (including negative) * * @param rngName fully-qualified name of the RNG * * @param filename name of the RNG's datafile * * @return psuedo-random integer */ public static int rng_next_int_internal( int n, String rngName, String filename) throws SQLException { File file = new File(filename); try { Random random = readSerialized(file); int value; if (n < 0) { value = random.nextInt(); } else { value = random.nextInt(n); } writeSerialized(file, random); return value; } catch (Throwable ex) { throw FarragoJdbcUtil.newSqlException(ex, tracer); } } public static RngmodelPackage getRngModelPackage(FarragoRepos repos) { return (RngmodelPackage) repos.getFarragoPackage().refPackage("RNGModel"); } // TODO: file lock public static void writeSerialized( File file, Random random) throws IOException { FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream(file); oos = new ObjectOutputStream(fos); oos.writeObject(random); oos.close(); oos = null; fos.close(); fos = null; } finally { Util.squelchStream(oos); Util.squelchStream(fos); } } public static Random readSerialized( File file) throws Exception { FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream(file); ois = new ObjectInputStream(fis); return (Random) ois.readObject(); } finally { Util.squelchStream(ois); Util.squelchStream(fis); } } static String getFilename(RngRandomNumberGenerator rng) { return FarragoProperties.instance().expandProperties( rng.getSerializedFile()); } } // End FarragoRngUDR.java eigenbase-farrago-0.9.0/examples/rng/src/net/sf/farrago/rng/FarragoRngDdlHandler.java0000444000175000017500000000562611173714170030403 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngDdlHandler.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.rng; import net.sf.farrago.ddl.*; import net.sf.farrago.session.*; import net.sf.farrago.util.*; import net.sf.farrago.rngmodel.rngschema.*; import net.sf.farrago.rng.resource.*; import java.net.*; import java.io.*; import java.util.*; import org.eigenbase.util.*; /** * FarragoRngDdlHandler defines handler methods for random number generator DDL. * * @author John V. Sichi * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/FarragoRngDdlHandler.java#7 $ */ public class FarragoRngDdlHandler extends DdlHandler { FarragoRngDdlHandler( FarragoSessionDdlValidator validator) { super(validator); } public void validateDefinition(RngRandomNumberGenerator rng) { String path = rng.getSerializedFile(); String expandedPath = FarragoProperties.instance().expandProperties(path); if (path.equals(expandedPath)) { rng.setSerializedFile(new File(path).getAbsolutePath()); } } public void executeCreation(RngRandomNumberGenerator rng) { Random random; Long seed = rng.getInitialSeed(); if (seed == null) { random = new Random(); } else { random = new Random(seed.longValue()); } try { FarragoRngUDR.writeSerialized( new File(FarragoRngUDR.getFilename(rng)), random); } catch (Throwable ex) { throw FarragoRngPluginFactory.res.RngFileCreationFailed.ex( validator.getRepos().getLocalizedObjectName( rng.getSerializedFile()), validator.getRepos().getLocalizedObjectName(rng), ex); } } public void executeDrop(RngRandomNumberGenerator rng) { File file = new File(rng.getSerializedFile()); file.delete(); } } // End FarragoRngDdlHandler.java eigenbase-farrago-0.9.0/examples/rng/unitsql/0000755000175000017500000000000011173714170021062 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/customBuild.properties0000644000175000017500000000013011173714170021361 0ustar drazzibdrazzibrelease.gpl=true release.properties.source=${luciddb.dir}/src/FarragoRelease.properties eigenbase-farrago-0.9.0/farragoenv.sh0000444000175000017500000000221211173714170017440 0ustar drazzibdrazzib# $Id: //open/dev/farrago/farragoenv.sh#6 $ # Script to set properties for locations of third-party # components needed by Farrago. Environment variables which are already set # are not modified. if [ -z "$1" ] then echo "Usage: . farragoenv.sh /path/to/open/thirdparty" return fi if [ ! -e "$1/build.properties" ] then echo "Usage: . farragoenv.sh /path/to/open/thirdparty" echo "build.properties not found in $1" fi if [ -z "$JAVA_HOME" ] then echo 'You must define environment variable JAVA_HOME' return fi THIRDPARTY_HOME=$1 if [ -z "$ANT_HOME" ]; then # if ANT_HOME is unset, use the one under thirdparty export ANT_HOME=$THIRDPARTY_HOME/ant export PATH=$ANT_HOME/bin:$PATH else # REVIEW jvs 19-Nov-2005: disabling this to see if it's # breaking LucidEra CruiseControl # otherwise, prepend ANT if not already present on PATH # ANT_BIN=$(cd $ANT_HOME/bin; pwd) # CURR_ANT=$(dirname `/usr/bin/which ant 2>&1 | cut -d " " -f 1`) # if [ "$CURR_ANT" != "$ANT_BIN" ]; then # export PATH=$ANT_BIN:$PATH # fi # unset -v ANT_BIN CURR_ANT export PATH=$ANT_HOME/bin:$PATH fi eigenbase-farrago-0.9.0/defineFarragoRuntime.sh0000444000175000017500000000066211173714170021415 0ustar drazzibdrazzib# Define variables needed by runtime scripts such as farragoServer. # This script is meant to be sourced from other scripts, not # executed directly. BASE_JAVA_ARGS="-ea -esa -cp `cat classpath.gen` \ -Dnet.sf.farrago.home=. \ -Djava.util.logging.config.file=trace/FarragoTrace.properties" SERVER_JAVA_ARGS="-Xss768K ${BASE_JAVA_ARGS}" # TODO: trim this CLIENT_JAVA_ARGS=${BASE_JAVA_ARGS} SQLLINE_JAVA_ARGS="sqlline.SqlLine" eigenbase-farrago-0.9.0/build.xml0000444000175000017500000022075411173714170016610 0ustar drazzibdrazzib ]> Configuring repository schema at: ${gensch.net.sf.farrago.dev.connection.schema.url} Trace net.sf.farrago.dynamic.level=FINE will cause ant test to fail or run very slowly; please disable it and try again. Oracle tests were requested via oracle.test, but Oracle is not available. cccp eigenbase-farrago-0.9.0/sqllineEngine0000555000175000017500000000061511173714170017502 0ustar drazzibdrazzib#!/bin/bash # $Id: //open/dev/farrago/sqllineEngine#3 $ # Run the sqlline command-line SQL interpreter # with an embedded Farrago engine source ./defineFarragoRuntime.sh if java ${SERVER_JAVA_ARGS} ${SQLLINE_JAVA_ARGS} \ -u jdbc:farrago: -d net.sf.farrago.jdbc.engine.FarragoJdbcEngineDriver \ -n sa $*; then echo else tset echo "Terminal reset because sqlline crashed" fi eigenbase-farrago-0.9.0/VERSION0000644000175000017500000000141511173714170016030 0ustar drazzibdrazzibeigenbase-0.9.0 Perforce change @12644 # A Perforce Label Specification. # # Label: The label name. # Update: The date this specification was last modified. # Access: The date of the last 'labelsync' on this label. # Owner: The user who created this label. # Description: A short description of the label (optional). # Options: Label update options: locked or unlocked. # Revision: Optional revision specification to make an automatic label. # View: Lines to select depot files for the label. # # Use 'p4 help label' to see more about label views. Label: eigenbase_r0.9.0 Update: 2009/04/22 12:06:10 Access: 2009/04/22 12:16:46 Owner: jvs Description: Eigenbase release 0.9.0 (candidate) Options: unlocked View: //open/dev/... eigenbase-farrago-0.9.0/jdbc4/0000755000175000017500000000000011173714170015745 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/jdbc4/NClob.java0000444000175000017500000000307711173714170017612 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/NClob.java#3 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Dummy interface for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/NClob.java#3 $ */ public interface NClob { } // End NClob.java eigenbase-farrago-0.9.0/jdbc4/SQLXML.java0000444000175000017500000000310311173714170017623 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/SQLXML.java#3 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Dummy interface for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/SQLXML.java#3 $ */ public interface SQLXML { } // End SQLXML.java eigenbase-farrago-0.9.0/jdbc4/UnwrappableRJConnection14.java0000444000175000017500000000406111173714170023510 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/UnwrappableRJConnection14.java#5 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; import org.objectweb.rmijdbc.*; import java.util.*; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Gunk for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/UnwrappableRJConnection14.java#5 $ */ public abstract class UnwrappableRJConnection extends RJConnection { static final long serialVersionUID = 8754470401040578510L; protected UnwrappableRJConnection(RJConnectionInterface rmiconn) { super(rmiconn); } protected UnwrappableRJConnection( RJDriverInterface drv, String url, Properties info) throws Exception { super(drv, url, info); } } // End UnwrappableRJConnection.java eigenbase-farrago-0.9.0/jdbc4/Unwrappable16.java0000444000175000017500000000355511173714170021245 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/Unwrappable16.java#3 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; import java.sql.*; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Gunk for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/Unwrappable16.java#3 $ */ public abstract class Unwrappable implements Wrapper { // implement Wrapper public boolean isWrapperFor(Class iface) { return false; } // implement Wrapper public T unwrap(Class iface) { throw new UnsupportedOperationException("unwrap"); } } // End Unwrappable.java eigenbase-farrago-0.9.0/jdbc4/UnwrappableRJConnection16.java0000444000175000017500000000452111173714170023513 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/UnwrappableRJConnection16.java#5 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; import org.objectweb.rmijdbc.*; import java.sql.*; import java.util.*; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Gunk for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/UnwrappableRJConnection16.java#5 $ */ public abstract class UnwrappableRJConnection extends RJConnection implements Wrapper { static final long serialVersionUID = 8754470401040578510L; protected UnwrappableRJConnection(RJConnectionInterface rmiconn) { super(rmiconn); } protected UnwrappableRJConnection( RJDriverInterface drv, String url, Properties info) throws Exception { super(drv, url, info); } // implement Wrapper public boolean isWrapperFor(Class iface) { return false; } // implement Wrapper public T unwrap(Class iface) { throw new UnsupportedOperationException("unwrap"); } } // End UnwrappableRJConnection.java eigenbase-farrago-0.9.0/jdbc4/RowId.java0000444000175000017500000000307711173714170017641 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/RowId.java#3 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Dummy interface for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/RowId.java#3 $ */ public interface RowId { } // End RowId.java eigenbase-farrago-0.9.0/jdbc4/RowIdLifetime.java0000444000175000017500000000313711173714170021315 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/RowIdLifetime.java#3 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Dummy interface for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/RowIdLifetime.java#3 $ */ public interface RowIdLifetime { } // End RowIdLifetime.java eigenbase-farrago-0.9.0/jdbc4/README0000444000175000017500000000026511173714170016626 0ustar drazzibdrazzibThese files are only incorporated into the build (via copy to src/org/eigenbase/jdbc4) for Java 1.5 builds. See http://pub.eigenbase.org/wiki/Jdbc4Transition for more information. eigenbase-farrago-0.9.0/jdbc4/Unwrappable14.java0000444000175000017500000000312511173714170021234 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/jdbc4/Unwrappable14.java#3 $ // Package org.eigenbase is a class library of data management components. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLstream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.eigenbase.jdbc4; // NOTE jvs 8-Oct 2008: If you are looking at the copy of this file under // farrago/src/org/eigenbase/jdbc4, do not try to edit it or check it out. // The original is checked into Perforce under farrago/jdbc4, and // gets copied to farrago/src/org/eigenbase/jdbc4 by ant createCatalog. /** * Gunk for JDBC 4 source compatibility. * See Eigenpedia. * * @author John Sichi * @version $Id: //open/dev/farrago/jdbc4/Unwrappable14.java#3 $ */ public abstract class Unwrappable { } // End Unwrappable.java eigenbase-farrago-0.9.0/ext/0000755000175000017500000000000011173714170015557 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/0000755000175000017500000000000011173714170016350 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/build.xml0000444000175000017500000000473011173714170020173 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/ext/mql/src/0000755000175000017500000000000011173714170017137 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/src/net/0000755000175000017500000000000011173714170017725 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/src/net/sf/0000755000175000017500000000000011173714170020335 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/0000755000175000017500000000000011173714170021756 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/0000755000175000017500000000000011173714170023712 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/0000755000175000017500000000000011173714170024503 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/package.html0000444000175000017500000000121011173714170026754 0ustar drazzibdrazzib Package net.sf.farrago.namespace.mql Defines a Farrago SQL/MED namespace implementation for MQL.
Revision $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/package.html#2 $
Copyright Copyright (C) 2009-2009 The Eigenbase Project
Copyright (C) 2009-2009 SQLStream, Inc.
Copyright (C) 2009-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlDataServer.java0000444000175000017500000001430111173714170030503 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlDataServer.java#4 $ // Farrago is an extensible data management system. // Copyright (C) 2009-2009 The Eigenbase Project // Copyright (C) 2009-2009 SQLstream, Inc. // Copyright (C) 2009-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.namespace.mql; import java.sql.*; import java.util.*; import javax.sql.*; import net.sf.farrago.namespace.*; import net.sf.farrago.namespace.impl.*; import net.sf.farrago.resource.*; import net.sf.farrago.type.*; import org.eigenbase.rel.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.sql.type.*; /** * MedMqlDataServer provides an implementation of the {@link * FarragoMedDataServer} interface for MQL. * * @author John V. Sichi * @version $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlDataServer.java#4 $ */ class MedMqlDataServer extends MedAbstractDataServer { //~ Static fields/initializers --------------------------------------------- public static final String PROP_URL = "URL"; public static final String PROP_METAWEB_TYPE = "METAWEB_TYPE"; public static final String PROP_UDX_SPECIFIC_NAME = "UDX_SPECIFIC_NAME"; public static final String DEFAULT_URL = "http://api.freebase.com/api/service/mqlread"; public static final String DEFAULT_UDX_SPECIFIC_NAME = "LOCALDB.METAWEB.MQL_QUERY"; //~ Instance fields -------------------------------------------------------- private MedAbstractDataWrapper wrapper; private String url; //~ Constructors ----------------------------------------------------------- MedMqlDataServer( MedAbstractDataWrapper wrapper, String serverMofId, Properties props) { super(serverMofId, props); this.wrapper = wrapper; } //~ Methods ---------------------------------------------------------------- void initialize() throws SQLException { Properties props = getProperties(); url = props.getProperty(PROP_URL, DEFAULT_URL); } // implement FarragoMedDataServer public FarragoMedNameDirectory getNameDirectory() throws SQLException { return null; } // implement FarragoMedDataServer public FarragoMedColumnSet newColumnSet( String [] localName, Properties tableProps, FarragoTypeFactory typeFactory, RelDataType rowType, Map columnPropMap) throws SQLException { String udxSpecificName = getProperties().getProperty( PROP_UDX_SPECIFIC_NAME, DEFAULT_UDX_SPECIFIC_NAME); requireProperty(tableProps, PROP_METAWEB_TYPE); String metawebType = tableProps.getProperty(PROP_METAWEB_TYPE); return new MedMqlColumnSet( this, localName, rowType, metawebType, udxSpecificName); } // implement FarragoMedDataServer public void registerRules(RelOptPlanner planner) { super.registerRules(planner); // pushdown rules // case 1: projection on top of a filter (with push down projection) // ie: filtering on variables which are not in projection planner.addRule( new MedMqlPushDownRule( new RelOptRuleOperand( ProjectRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand( FilterRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand(ProjectRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand( MedMqlTableRel.class) }) }) }), "proj on filter on proj")); // case 2: filter with push down projection // ie: proj only has values which are already in filter expression planner.addRule( new MedMqlPushDownRule( new RelOptRuleOperand( FilterRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand(ProjectRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand( MedMqlTableRel.class) }) }), "filter on proj")); // case 3: filter with no projection to push down. // ie: select * planner.addRule( new MedMqlPushDownRule( new RelOptRuleOperand( FilterRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand(MedMqlTableRel.class) }), "filter")); // case 4: only projection, no filter planner.addRule( new MedMqlPushDownRule( new RelOptRuleOperand( ProjectRel.class, new RelOptRuleOperand[] { new RelOptRuleOperand(MedMqlTableRel.class) }), "proj")); // case 5: neither projection nor filter planner.addRule( new MedMqlPushDownRule( new RelOptRuleOperand(MedMqlTableRel.class), "none")); } MedAbstractDataWrapper getWrapper() { return wrapper; } public String getUrl() { return url; } } // End MedMqlDataServer.java eigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlForeignDataWrapper.java0000444000175000017500000000546211173714170032177 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlForeignDataWrapper.java#3 $ // Farrago is an extensible data management system. // Copyright (C) 2009-2009 The Eigenbase Project // Copyright (C) 2009-2009 SQLstream, Inc. // Copyright (C) 2009-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.namespace.mql; import java.sql.*; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.namespace.*; import net.sf.farrago.namespace.impl.*; import net.sf.farrago.resource.*; /** * MedMqlForeignDataWrapper provides an implementation of the {@link * FarragoMedDataWrapper} interface for MQL. * * @author John V. Sichi * @version $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlForeignDataWrapper.java#3 $ */ public class MedMqlForeignDataWrapper extends MedAbstractDataWrapper { //~ Constructors ----------------------------------------------------------- /** * Creates a new data wrapper instance. */ public MedMqlForeignDataWrapper() { } //~ Methods ---------------------------------------------------------------- // implement FarragoMedDataWrapper public String getSuggestedName() { return "MQL_FOREIGN_DATA_WRAPPER"; } // implement FarragoMedDataWrapper public String getDescription(Locale locale) { // TODO jvs 6-Jan-2008: i18n return "Foreign data wrapper for MQL"; } // TODO jvs 6-Jan-2008: implement getServerPropertyInfo // implement FarragoMedDataWrapper public FarragoMedDataServer newServer( String serverMofId, Properties props) throws SQLException { MedMqlDataServer server = new MedMqlDataServer( this, serverMofId, props); boolean success = false; try { server.initialize(); success = true; return server; } finally { if (!success) { server.closeAllocation(); } } } } // End MedMqlForeignDataWrapper.java eigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlUdx.java0000444000175000017500000002052111173714170027204 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlUdx.java#4 $ // Farrago is an extensible data management system. // Copyright (C) 2008-2009 The Eigenbase Project // Copyright (C) 2008-2009 SQLStream, Inc. // Copyright (C) 2008-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.namespace.mql; import java.net.*; import java.io.*; import java.sql.*; import java.util.*; import java.util.logging.*; import net.sf.farrago.trace.*; /** * MedMqlUdx is the UDX which implements the execution of an MQL query * generated by the optimizer. * * @author John Sichi * @version $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlUdx.java#4 $ */ public abstract class MedMqlUdx { private static final Logger tracer = FarragoTrace.getClassTracer(MedMqlUdx.class); public static void execute( String urlBase, String mql, String rowType, PreparedStatement resultInserter) throws Exception { boolean tracing = tracer.isLoggable(Level.FINE); // FIXME jvs 7-Jan-2008: use a proper JSON library // for all of this if (tracing) { tracer.fine(mql); } Map rowMap = new HashMap(); String [] colNames = rowType.split("\\|"); if (tracing) { tracer.fine("Mapped columns = " + Arrays.asList(colNames)); } int iColumn = 1; for (String colName : colNames) { rowMap.put(colName, iColumn); ++iColumn; } String escaped = escapeUri(mql); String urlString = urlBase + "?query=" + escaped; if (tracing) { tracer.fine(urlString); } URL url = new URL(urlString); InputStream inputStream = null; try { inputStream = url.openStream(); InputStreamReader reader = new InputStreamReader(inputStream); LineNumberReader lineReader = new LineNumberReader(reader); boolean readingResult = false; boolean readingRow = false; for (;;) { String line = lineReader.readLine(); if (line == null) { return; } if (tracing) { tracer.fine(line); } line = line.trim(); if (!readingResult) { if (line.startsWith("\"result\"")) { readingResult = true; } continue; } if (!readingRow) { if (line.startsWith("{")) { readingRow = true; } else if (line.startsWith("]")) { readingResult = false; } continue; } if (line.startsWith("}")) { resultInserter.executeUpdate(); readingRow = false; continue; } if (!line.startsWith("\"")) { continue; } int iColon = line.indexOf(':'); if (iColon == -1) { continue; } String colName = line.substring(1, iColon - 1); Integer iParam = rowMap.get(colName); if (iParam == null) { continue; } line = line.substring(iColon + 1); if (line.startsWith("\"")) { int iEndQuote = line.indexOf("\"", 1); if (iEndQuote == -1) { continue; } line = line.substring(1, iEndQuote); } resultInserter.setString(iParam, line); } } finally { if (inputStream != null) { inputStream.close(); } } } // NOTE jvs 8-Jan-2009: code below was taken from // http://www.w3.org/International/URLUTF8Encoder.java private final static String[] hex = { "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09", "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f", "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27", "%28", "%29", "%2a", "%2b", "%2c", "%2d", "%2e", "%2f", "%30", "%31", "%32", "%33", "%34", "%35", "%36", "%37", "%38", "%39", "%3a", "%3b", "%3c", "%3d", "%3e", "%3f", "%40", "%41", "%42", "%43", "%44", "%45", "%46", "%47", "%48", "%49", "%4a", "%4b", "%4c", "%4d", "%4e", "%4f", "%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57", "%58", "%59", "%5a", "%5b", "%5c", "%5d", "%5e", "%5f", "%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67", "%68", "%69", "%6a", "%6b", "%6c", "%6d", "%6e", "%6f", "%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77", "%78", "%79", "%7a", "%7b", "%7c", "%7d", "%7e", "%7f", "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", "%88", "%89", "%8a", "%8b", "%8c", "%8d", "%8e", "%8f", "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f", "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7", "%a8", "%a9", "%aa", "%ab", "%ac", "%ad", "%ae", "%af", "%b0", "%b1", "%b2", "%b3", "%b4", "%b5", "%b6", "%b7", "%b8", "%b9", "%ba", "%bb", "%bc", "%bd", "%be", "%bf", "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7", "%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf", "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", "%d8", "%d9", "%da", "%db", "%dc", "%dd", "%de", "%df", "%e0", "%e1", "%e2", "%e3", "%e4", "%e5", "%e6", "%e7", "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef", "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", "%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff" }; private static String escapeUri(String s) { StringBuffer sbuf = new StringBuffer(); int len = s.length(); for (int i = 0; i < len; i++) { int ch = s.charAt(i); if ('A' <= ch && ch <= 'Z') { // 'A'..'Z' sbuf.append((char)ch); } else if ('a' <= ch && ch <= 'z') { // 'a'..'z' sbuf.append((char)ch); } else if ('0' <= ch && ch <= '9') { // '0'..'9' sbuf.append((char)ch); } else if (ch == ' ') { // space sbuf.append('+'); } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!' || ch == '~' || ch == '*' || ch == '\'' || ch == '(' || ch == ')') { // unreserved sbuf.append((char)ch); } else if (ch <= 0x007f) { // other ASCII sbuf.append(hex[ch]); } else if (ch <= 0x07FF) { // non-ASCII <= 0x7FF sbuf.append(hex[0xc0 | (ch >> 6)]); sbuf.append(hex[0x80 | (ch & 0x3F)]); } else { // 0x7FF < ch <= 0xFFFF sbuf.append(hex[0xe0 | (ch >> 12)]); sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]); sbuf.append(hex[0x80 | (ch & 0x3F)]); } } return sbuf.toString(); } } // End MedMqlUdx.java eigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlTableRel.java0000444000175000017500000000341711173714170030143 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlTableRel.java#2 $ // Farrago is an extensible data management system. // Copyright (C) 2009-2009 The Eigenbase Project // Copyright (C) 2009-2009 SQLstream, Inc. // Copyright (C) 2009-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.namespace.mql; import org.eigenbase.rel.*; import org.eigenbase.relopt.*; /** * MedMqlTableRel represents a logical access to an MQL foreign table * before any pushdown. * * @author John Sichi * @version $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlTableRel.java#2 $ */ class MedMqlTableRel extends TableAccessRelBase { public MedMqlTableRel( RelOptCluster cluster, RelOptTable table, RelOptConnection connection) { super( cluster, new RelTraitSet(CallingConvention.NONE), table, connection); } MedMqlColumnSet getMedMqlColumnSet() { return (MedMqlColumnSet) getTable(); } } // End MedMqlTableRel.java eigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlPushDownRule.java0000444000175000017500000003424211173714170031050 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlPushDownRule.java#4 $ // Farrago is an extensible data management system. // Copyright (C) 2009-2009 The Eigenbase Project // Copyright (C) 2009-2009 SQLstream, Inc. // Copyright (C) 2009-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.namespace.mql; import java.util.*; import java.text.*; import java.math.*; import java.io.*; import net.sf.farrago.query.*; import org.eigenbase.rel.*; import org.eigenbase.rel.rules.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.rex.*; import org.eigenbase.sql.*; import org.eigenbase.sql.fun.*; import org.eigenbase.sql.type.*; import org.eigenbase.util.*; /** * MedMqlPushDownRule is an optimizer rule to push filters and * projections down into MQL. * * @author John Sichi * @version $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlPushDownRule.java#4 $ */ class MedMqlPushDownRule extends RelOptRule { /** * Creates a MedMqlPushDownRule. */ public MedMqlPushDownRule(RelOptRuleOperand operand, String id) { super(operand, "MedMqlPushDownRule: " + id); } // implement RelOptRule public void onMatch(RelOptRuleCall call) { // TODO jvs 7-Jan-2009: factor out code shared with // MedJdbcPushDownRule into net.sf.farrago.namespace.impl boolean projOnFilter = false; boolean filterOnProj = false; boolean filterOnly = false; boolean projectOnly = false; if (description.contains("proj on filter")) { projOnFilter = true; } else if (description.contains("filter on proj")) { filterOnProj = true; } else if (description.contains("filter")) { filterOnly = true; } else if (description.contains("proj")) { projectOnly = true; } int relLength = call.rels.length; MedMqlTableRel tableRel = (MedMqlTableRel) call.rels[relLength - 1]; if (relLength == 1) { // no filter, no project, no problem transformToFarragoUdxRel( call, tableRel, null, null, null); return; } ProjectRel topProj = null; ProjectRel origTopProj = null; FilterRel filter = null; ProjectRel bottomProj = null; ProjectRel origBottomProj = null; ProjectRel newTopProject = null; if (!projectOnly && !filterOnly) { filter = (FilterRel) call.rels[relLength - 3]; } else if (filterOnly) { filter = (FilterRel) call.rels[relLength - 2]; } if (projOnFilter) { topProj = (ProjectRel) call.rels[0]; origTopProj = topProj; // handle any expressions in the projection PushProjector pushProject = new PushProjector( topProj, null, filter.getChild(), PushProjector.ExprCondition.FALSE); ProjectRel newProj = pushProject.convertProject(null); if (newProj != null) { topProj = (ProjectRel) newProj.getChild(); newTopProject = newProj; } else { // nothing to push down projOnFilter = false; newTopProject = topProj; filterOnProj = true; } } if (!filterOnly) { bottomProj = (ProjectRel) call.rels[relLength - 2]; origBottomProj = bottomProj; if (projectOnly) { PushProjector pushProject = new PushProjector( bottomProj, null, tableRel, PushProjector.ExprCondition.FALSE); ProjectRel newProj = pushProject.convertProject(null); if (newProj != null) { bottomProj = (ProjectRel) newProj.getChild(); newTopProject = newProj; } } } RexBuilder rexBuilder = tableRel.getCluster().getRexBuilder(); RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory(); SqlOperator op = null; RexNode[] operands = null; if (!projectOnly) { RexCall filterCall = (RexCall) filter.getCondition(); op = filterCall.getOperator(); operands = filterCall.getOperands(); } Map fieldBindings = createFieldBindings(tableRel); String[] allOrigFieldNames = RelOptUtil.getFieldNames(tableRel.getRowType()); RelDataType[] finalRowTypes = new RelDataType[allOrigFieldNames.length]; String[] fieldNames = allOrigFieldNames; if (!filterOnly) { fieldBindings = new TreeMap(); RelDataTypeField[] projFields = bottomProj.getRowType().getFields(); fieldNames = new String[projFields.length]; RexNode[] nodes = bottomProj.getChildExps(); for (int i = 0; i < nodes.length; i++) { if (nodes[i] instanceof RexInputRef) { int x = ((RexInputRef)nodes[i]).getIndex(); fieldNames[i] = allOrigFieldNames[x]; } else { // can't handle transformToFarragoUdxRel( call, tableRel, filter, origTopProj, origBottomProj); return; } } finalRowTypes = new RelDataType[fieldNames.length]; for (int i = 0; i < projFields.length; i++) { finalRowTypes[i] = projFields[i].getType(); fieldBindings.put(projFields[i].getName(), null); } } if (!validProjection(fieldNames)) { transformToFarragoUdxRel( call, tableRel, filter, origTopProj, origBottomProj); return; } // TODO jvs 8-Jan-2009: In the case of a query like // select "name" from metaweb.artists where "id" = '/en/gene_kelly'; // we don't push down the projection because we don't find // out that we don't need the "id" field for filter // post-processing until it's too late. The filter pushdown // needs to eliminate the projections which become // redundant. RexNode filterRemainder = null; if (filter != null) { filterRemainder = translateFilter( filter, fieldNames, fieldBindings); } RelDataType resultType; if (!filterOnly) { RelDataType newRowType = typeFactory.createStructType(finalRowTypes, fieldNames); resultType = typeFactory.createTypeWithNullability(newRowType, true); } else { resultType = typeFactory.createTypeWithNullability( tableRel.getRowType(), true); } RelNode rel = createFarragoUdxRel( tableRel, resultType, fieldBindings); if (filterRemainder != null) { rel = new FilterRel(rel.getCluster(), rel, filterRemainder); } if (origTopProj != null) { rel = new ProjectRel( origTopProj.getCluster(), rel, origTopProj.getProjectExps(), origTopProj.getRowType(), origTopProj.getFlags(), origTopProj.getCollationList()); } if (projectOnly && newTopProject != null) { rel = new ProjectRel( newTopProject.getCluster(), rel, newTopProject.getProjectExps(), newTopProject.getRowType(), newTopProject.getFlags(), newTopProject.getCollationList()); } call.transformTo(rel); } // TODO jvs 8-Jan-2009: use org.eigenbase.sarg for comprehensive // filter translation private RexNode translateFilter( FilterRel filterRel, String [] fieldNames, Map fieldBindings) { RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder(); List nodeList = new ArrayList(); RelOptUtil.decomposeConjunction(filterRel.getCondition(), nodeList); Iterator iter = nodeList.iterator(); while (iter.hasNext()) { RexNode node = iter.next(); if (!(node instanceof RexCall)) { continue; } RexCall call = (RexCall) node; if (call.getOperator() != SqlStdOperatorTable.equalsOperator) { continue; } final RexNode [] operands = call.getOperands(); RexNode op0 = operands[0]; RexNode op1 = operands[1]; if ((op1 instanceof RexInputRef) && (op0 instanceof RexLiteral)) { RexNode tmp = op0; op0 = op1; op1 = tmp; } if ((op0 instanceof RexInputRef) && (op1 instanceof RexLiteral)) { iter.remove(); RexInputRef inputRef = (RexInputRef) op0; String fieldName = fieldNames[inputRef.getIndex()]; RexLiteral literal = (RexLiteral) op1; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); // REVIEW jvs 8-Jan-2009: study Java vs JSON conventions literal.printAsJava(pw); pw.close(); String value = sw.toString(); fieldBindings.put(fieldName, value); } } if (nodeList.isEmpty()) { return null; } RexNode remainder = RexUtil.andRexNodeList(rexBuilder, nodeList); return remainder; } private boolean validProjection(String[] fieldNames) { // detect duplicate names Set names = new HashSet(); for (String fieldName : fieldNames) { if (!names.add(fieldName)) { // conflict return false; } } return true; } private Map createFieldBindings( MedMqlTableRel tableRel) { Map fieldBindings = new TreeMap(); for (RelDataTypeField field : tableRel.getRowType().getFieldList()) { fieldBindings.put(field.getName(), null); } return fieldBindings; } private RelNode createFarragoUdxRel( MedMqlTableRel tableRel, RelDataType rowType, Map fieldBindings) { MedMqlColumnSet columnSet = tableRel.getMedMqlColumnSet(); RexBuilder rexBuilder = tableRel.getCluster().getRexBuilder(); // FIXME jvs 7-Jan-2008: escape quotes in field names; use a proper // JSON library StringBuilder sbMql = new StringBuilder(); sbMql.append("{\"query\":"); sbMql.append("[{\"type\":\""); sbMql.append(columnSet.metawebType); sbMql.append("\""); for (Map.Entry entry : fieldBindings.entrySet()) { sbMql.append(",\""); sbMql.append(entry.getKey()); sbMql.append("\":"); if (entry.getValue() == null) { sbMql.append("null"); } else { sbMql.append(entry.getValue()); } } sbMql.append("}]"); sbMql.append("}"); String mql = sbMql.toString(); StringBuilder sbRowType = new StringBuilder(); boolean first = true; for (RelDataTypeField field : rowType.getFields()) { if (first) { first = false; } else { sbRowType.append("|"); } sbRowType.append(field.getName()); } String rowTypeString = sbRowType.toString(); RexNode urlArg = rexBuilder.makeLiteral(columnSet.server.getUrl()); RexNode mqlArg = rexBuilder.makeLiteral(mql); RexNode rowTypeArg = rexBuilder.makeLiteral(rowTypeString); RelNode rel = FarragoJavaUdxRel.newUdxRel( columnSet.getPreparingStmt(), rowType, columnSet.udxSpecificName, columnSet.server.getServerMofId(), new RexNode[] { urlArg, mqlArg, rowTypeArg }, RelNode.emptyArray); return rel; } private void transformToFarragoUdxRel( RelOptRuleCall call, MedMqlTableRel tableRel, FilterRel filter, ProjectRel topProj, ProjectRel bottomProj) { MedMqlColumnSet columnSet = tableRel.getMedMqlColumnSet(); RelNode rel = createFarragoUdxRel( tableRel, tableRel.getRowType(), createFieldBindings(tableRel)); if (bottomProj != null) { rel = new ProjectRel( bottomProj.getCluster(), rel, bottomProj.getProjectExps(), bottomProj.getRowType(), bottomProj.getFlags(), bottomProj.getCollationList()); } if (filter != null) { rel = new FilterRel( filter.getCluster(), rel, filter.getCondition()); } if (topProj != null) { rel = new ProjectRel( topProj.getCluster(), rel, topProj.getProjectExps(), topProj.getRowType(), topProj.getFlags(), topProj.getCollationList()); } call.transformTo(rel); } } // End MedMqlPushDownRule.java eigenbase-farrago-0.9.0/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlColumnSet.java0000444000175000017500000000543111173714170030360 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlColumnSet.java#3 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.namespace.mql; import java.math.*; import java.sql.*; import java.util.*; import net.sf.farrago.namespace.*; import net.sf.farrago.namespace.impl.*; import net.sf.farrago.query.*; import net.sf.farrago.type.*; import net.sf.farrago.util.*; import org.eigenbase.rel.*; import org.eigenbase.rel.convert.*; import org.eigenbase.rel.jdbc.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.rex.*; import org.eigenbase.sql.*; import org.eigenbase.util.*; /** * MedMqlColumnSet provides an implementation of the {@link * FarragoMedColumnSet} interface for MQL. * * @author John V. Sichi * @version $Id: //open/dev/farrago/ext/mql/src/net/sf/farrago/namespace/mql/MedMqlColumnSet.java#3 $ */ class MedMqlColumnSet extends MedAbstractColumnSet { //~ Instance fields -------------------------------------------------------- final MedMqlDataServer server; final String metawebType; final String udxSpecificName; //~ Constructors ----------------------------------------------------------- MedMqlColumnSet( MedMqlDataServer server, String [] localName, RelDataType rowType, String metawebType, String udxSpecificName) { super(localName, null, rowType, null, null); this.server = server; this.udxSpecificName = udxSpecificName; this.metawebType = metawebType; } //~ Methods ---------------------------------------------------------------- // implement RelOptTable public RelNode toRel( RelOptCluster cluster, RelOptConnection connection) { return new MedMqlTableRel( cluster, this, connection); } } // End MedMqlColumnSet.java eigenbase-farrago-0.9.0/ext/mql/README0000444000175000017500000000014711173714170017230 0ustar drazzibdrazzibFor information on this MQL plugin for SQL/MED, see http://pub.eigenbase.org/wiki/FarragoMedMqlPlugin eigenbase-farrago-0.9.0/ext/mql/unitsql/0000755000175000017500000000000011173714170020047 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/vjdbc/0000755000175000017500000000000011173714170016647 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/ext/vjdbc/vjdbc-config.xml0000444000175000017500000000037511173714170021727 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/ext/vjdbc/web.xml0000444000175000017500000000134211173714170020144 0ustar drazzibdrazzib VJdbcServlet Servlet for using VJdbc over HTTP VJdbcServlet de.simplicit.vjdbc.server.servlet.ServletCommandSink config-resource /WEB-INF/vjdbc-config.xml VJdbcServlet /vjdbc eigenbase-farrago-0.9.0/plugin/0000755000175000017500000000000011173714170016255 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/plugin/buildPlugin.xml0000444000175000017500000003170711173714170021263 0ustar drazzibdrazzib Configuring repository schema at: ${gensch.net.sf.farrago.dev.connection.schema.url} eigenbase-farrago-0.9.0/plugin/templates/0000755000175000017500000000000011173714170020253 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/plugin/templates/jaas.config.tmpl0000444000175000017500000000006611173714170023333 0ustar drazzibdrazzibFarrago { @FARRAGO_LOGIN_MODULE@ Required; }; eigenbase-farrago-0.9.0/testcases/0000755000175000017500000000000011173714170016755 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/buildMacros.xml0000444000175000017500000013474311173714170017757 0ustar drazzibdrazzib ]> replaceme Database URL: ${cleanCatalog.net.sf.farrago.dev.connection.url} Executing: ${cleanCatalog.net.sf.farrago.dev.dropStorage} ${cleanCatalog.net.sf.farrago.dev.createStorage} eigenbase-farrago-0.9.0/dist/0000755000175000017500000000000011173714170015722 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/dist/bin/0000755000175000017500000000000011173714170016472 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/dist/bin/defineFarragoRuntime.bat0000444000175000017500000000135211173714170023261 0ustar drazzibdrazzibrem $Id: //open/dev/farrago/dist/bin/defineFarragoRuntime.bat#6 $ rem Define variables needed by runtime scripts such as farragoServer.bat. rem This script is meant to be sourced from other scripts, not rem executed directly. set MAIN_DIR=%~dp0.. if not exist "%MAIN_DIR%\bin\classpath.bat" goto need_install call "%MAIN_DIR%\bin\classpath.bat" set JAVA_ARGS=-Xms256m -Xmx256m -cp %LCP% -Dnet.sf.farrago.home="%MAIN_DIR%" -Djava.util.logging.config.file="%MAIN_DIR%\trace\Trace.properties" set SQLLINE_JAVA_ARGS=sqlline.SqlLine set JAVA_EXEC=%JAVA_HOME%\bin\java set PATH=%PATH%;%MAIN_DIR%\plugin;%MAIN_DIR%\lib\fennel goto done :need_install echo Error: "%MAIN_DIR%\install\install.bat" has not been run yet. exit /b 1 :done eigenbase-farrago-0.9.0/dist/bin/sqllineEngine.bat0000444000175000017500000000061011173714170021752 0ustar drazzibdrazzib@echo off rem $Id: //open/dev/farrago/dist/bin/sqllineEngine.bat#4 $ rem Run the sqlline command-line SQL interpreter rem with an embedded Farrago engine setlocal set MAIN_DIR=%~dp0.. call "%MAIN_DIR%\bin\defineFarragoRuntime.bat" if errorlevel 1 goto done %JAVA_EXEC% %JAVA_ARGS% %SQLLINE_JAVA_ARGS% -u jdbc:farrago: -d net.sf.farrago.jdbc.engine.FarragoJdbcEngineDriver -n sa %* :done eigenbase-farrago-0.9.0/dist/bin/defineFarragoRuntime.sh0000444000175000017500000000133611173714170023127 0ustar drazzibdrazzib# $Id: //open/dev/farrago/dist/bin/defineFarragoRuntime.sh#7 $ # Define variables needed by runtime scripts such as farragoServer. # This script is meant to be sourced from other scripts, not # executed directly. MAIN_DIR=$(cd `dirname $0`/..; pwd) if [ ! -e "$MAIN_DIR/bin/classpath.gen" ]; then echo "Error: $MAIN_DIR/install/install.sh has not been run yet." exit -1 fi JAVA_ARGS="-Xms256m -Xmx256m -cp `cat $MAIN_DIR/bin/classpath.gen` \ -Dnet.sf.farrago.home=$MAIN_DIR \ -Dorg.eigenbase.util.AWT_WORKAROUND=off \ -Djava.util.logging.config.file=$MAIN_DIR/trace/Trace.properties" SQLLINE_JAVA_ARGS="sqlline.SqlLine" JAVA_EXEC=${JAVA_HOME}/bin/java export LD_LIBRARY_PATH=$MAIN_DIR/plugin:$MAIN_DIR/lib/fennel eigenbase-farrago-0.9.0/dist/bin/sqllineEngine0000555000175000017500000000067011173714170021216 0ustar drazzibdrazzib#!/bin/sh # $Id: //open/dev/farrago/dist/bin/sqllineEngine#5 $ # Run the sqlline command-line SQL interpreter # with an embedded Farrago engine BIN_DIR=$(cd `dirname $0`; pwd) . $BIN_DIR/defineFarragoRuntime.sh if ${JAVA_EXEC} ${JAVA_ARGS} ${SQLLINE_JAVA_ARGS} \ -u jdbc:farrago: -d net.sf.farrago.jdbc.engine.FarragoJdbcEngineDriver \ -n sa $*; then echo else tset echo "Terminal reset because sqlline crashed" fi eigenbase-farrago-0.9.0/dist/bin/farragoServer.bat0000444000175000017500000000044211173714170021770 0ustar drazzibdrazzib@echo off rem $Id: //open/dev/farrago/dist/bin/farragoServer.bat#4 $ rem Run Farrago as a standalone RMI server setlocal set MAIN_DIR=%~dp0.. call "%MAIN_DIR%\bin\defineFarragoRuntime.bat" if errorlevel 1 goto done %JAVA_EXEC% %JAVA_ARGS% net.sf.farrago.server.FarragoVjdbcServer :done eigenbase-farrago-0.9.0/dist/bin/farragoServer0000555000175000017500000000036111173714170021226 0ustar drazzibdrazzib#!/bin/sh # $Id: //open/dev/farrago/dist/bin/farragoServer#4 $ # Run Farrago as a standalone RMI server BIN_DIR=$(cd `dirname $0`; pwd) . $BIN_DIR/defineFarragoRuntime.sh ${JAVA_EXEC} ${JAVA_ARGS} net.sf.farrago.server.FarragoVjdbcServer eigenbase-farrago-0.9.0/dist/bin/sqllineClient.bat0000444000175000017500000000062711173714170021773 0ustar drazzibdrazzib@echo off rem $Id: //open/dev/farrago/dist/bin/sqllineClient.bat#5 $ rem Run the sqlline command-line SQL interpreter as a client rem to a Farrago server setlocal set MAIN_DIR=%~dp0.. call "%MAIN_DIR%\bin\defineFarragoRuntime.bat" if errorlevel 1 goto done %JAVA_EXEC% %JAVA_ARGS% %SQLLINE_JAVA_ARGS% -u jdbc:farrago:rmi://localhost -d net.sf.farrago.jdbc.client.FarragoVjdbcClientDriver -n sa %* :done eigenbase-farrago-0.9.0/dist/bin/sqllineClient0000555000175000017500000000056711173714170021234 0ustar drazzibdrazzib#!/bin/sh # $Id: //open/dev/farrago/dist/bin/sqllineClient#6 $ # Run the sqlline command-line SQL interpreter as a client # to a Farrago server BIN_DIR=$(cd `dirname $0`; pwd) . $BIN_DIR/defineFarragoRuntime.sh ${JAVA_EXEC} ${JAVA_ARGS} ${SQLLINE_JAVA_ARGS} \ -u jdbc:farrago:rmi://localhost \ -d net.sf.farrago.jdbc.client.FarragoVjdbcClientDriver \ -n sa $* eigenbase-farrago-0.9.0/dist/build.xml0000444000175000017500000000745011173714170017547 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/dist/install/0000755000175000017500000000000011173714170017370 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/dist/install/install.bat0000444000175000017500000000245511173714170021532 0ustar drazzibdrazzib@echo off rem $Id: //open/dev/farrago/dist/install/install.bat#5 $ rem Farrago installation script setlocal set BASE_DIR=%~dp0.. set LIB_DIR=%BASE_DIR%\lib set BIN_DIR=%BASE_DIR%\bin set TRACE_DIR=%BASE_DIR%\trace set TRACE_CONFIG=%TRACE_DIR%\Trace.properties if "%JAVA_HOME%" == "" goto need_java if not exist "%TRACE_DIR%" mkdir "%TRACE_DIR%" echo # Tracing configuration> "%TRACE_CONFIG%" echo handlers=java.util.logging.FileHandler>> "%TRACE_CONFIG%" echo java.util.logging.FileHandler.append=true>> "%TRACE_CONFIG%" echo java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter>> "%TRACE_CONFIG%" echo java.util.logging.FileHandler.pattern=%TRACE_DIR:\=\\%\\Trace.log>> "%TRACE_CONFIG%" echo .level=CONFIG>> "%TRACE_CONFIG%" echo set JAVA_HOME="%JAVA_HOME%"> "%BIN_DIR%\classpath.bat" echo set LCP="%JAVA_HOME%\lib\tools.jar">> "%BIN_DIR%\classpath.bat" for %%j in ("%LIB_DIR%\*.jar") do echo set LCP=%%LCP%%;"%%j">> "%BIN_DIR%\classpath.bat" for %%j in ("%LIB_DIR%\mdrlibs\*.jar") do echo set LCP=%%LCP%%;"%%j">> "%BIN_DIR%\classpath.bat" for %%j in ("%LIB_DIR%\enki\*.jar") do echo set LCP=%%LCP%%;"%%j">> "%BIN_DIR%\classpath.bat" echo Installation successful goto end :need_java echo "The JAVA_HOME environment variable must be set to the location" echo "of a version 1.5 JVM." :end eigenbase-farrago-0.9.0/dist/install/install.sh0000555000175000017500000000206311173714170021374 0ustar drazzibdrazzib#!/bin/sh INSTALL_DIR=$(cd `dirname $0`; pwd) BASE_DIR=$(cd $INSTALL_DIR/..; pwd) LIB_DIR=$BASE_DIR/lib BIN_DIR=$BASE_DIR/bin TRACE_DIR=$BASE_DIR/trace cd $INSTALL_DIR if [ -z "$JAVA_HOME" ]; then echo "The JAVA_HOME environment variable must be set to the location" echo "of a version 1.5 JVM." exit 1; fi set -e set -v export LD_LIBRARY_PATH=$LIB_DIR/fennel # configure tracing mkdir $TRACE_DIR cat >$TRACE_DIR/Trace.properties <$BIN_DIR/classpath.gen eigenbase-farrago-0.9.0/dist/ExampleRelease.properties0000444000175000017500000000064011173714170022732 0ustar drazzibdrazzib# $Id: //open/dev/farrago/dist/ExampleRelease.properties#2 $ # Example information for Farrago release properties file package.name=eigenbase product.name=Eigenbase Data Management System product.version.major=0 product.version.minor=0 product.version.point=0 jdbc.driver.name=FarragoJdbcDriver jdbc.driver.version.major=0 jdbc.driver.version.minor=0 jdbc.url.base=jdbc:farrago: jdbc.url.port.default=5433 eigenbase-farrago-0.9.0/eclipse/0000755000175000017500000000000011173714170016403 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/eclipse/farrago.classpath0000444000175000017500000000067311173714170021734 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/eclipse/farrago.project0000444000175000017500000000055611173714170021420 0ustar drazzibdrazzib farrago org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature eigenbase-farrago-0.9.0/eclipse/codeFormat.xml0000444000175000017500000006351011173714170021213 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/eclipse/.settings/0000755000175000017500000000000011173714170020321 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/eclipse/.settings/org.eclipse.jdt.core.prefs0000444000175000017500000000221111173714170025275 0ustar drazzibdrazzib#Fri Sep 16 17:20:57 PDT 2005 eclipse.preferences.version=1 org.eclipse.jdt.core.builder.cleanOutputFolder=ignore org.eclipse.jdt.core.builder.duplicateResourceTask=warning org.eclipse.jdt.core.builder.invalidClasspath=abort org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch org.eclipse.jdt.core.circularClasspath=error org.eclipse.jdt.core.classpath.exclusionPatterns=enabled org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 org.eclipse.jdt.core.incompatibleJDKLevel=ignore org.eclipse.jdt.core.incompleteClasspath=error org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.5 eigenbase-farrago-0.9.0/initsql/0000755000175000017500000000000011173714170016442 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/initsql/createMgmtViews.sql0000444000175000017500000007415311173714170022301 0ustar drazzibdrazzib-- This script creates a view schema used for database management !set verbose true -- create views in system-owned schema sys_boot.mgmt create or replace schema sys_boot.mgmt; set schema 'sys_boot.mgmt'; set path 'sys_boot.mgmt'; create or replace function repository_properties() returns table(property_name varchar(255), property_value varchar(255)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.repositoryProperties'; create or replace view repository_properties_view as select * from table(repository_properties()); create or replace function repository_integrity_violations() returns table(description varchar(65535), mof_id varchar(128)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.repositoryIntegrityViolations'; create or replace function statements() returns table(id bigint, session_id bigint, sql_stmt varchar(1024), create_time timestamp, parameters varchar(1024)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.statements'; create or replace view statements_view as select * from table(statements()); -- todo: grant this only to a privileged user grant select on statements_view to public; create or replace function sessions() returns table(id int, url varchar(128), current_user_name varchar(128), current_role_name varchar(128), session_user_name varchar(128), system_user_name varchar(128), system_user_fullname varchar(128), session_name varchar(128), program_name varchar(128), process_id int, catalog_name varchar(128), schema_name varchar(128), is_closed boolean, is_auto_commit boolean, is_txn_in_progress boolean, label_name varchar(128)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.sessions'; create or replace view sessions_view as select * from table(sessions()); -- todo: grant this only to a privileged user grant select on sessions_view to public; create or replace function objects_in_use() returns table(session_id bigint, stmt_id bigint, mof_id varchar(128)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.objectsInUse'; create or replace view objects_in_use_view as select * from table(objects_in_use()); -- TODO: grant this only to a privileged user grant select on objects_in_use_view to public; create or replace function threads() returns table( thread_id bigint, thread_group_name varchar(128), thread_name varchar(128), thread_priority int, thread_state varchar(128), is_alive boolean, is_daemon boolean, is_interrupted boolean) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.threadList'; create or replace function thread_stack_entries() returns table( thread_id bigint, stack_level int, entry_string varchar(1024), class_name varchar(128), method_name varchar(128), file_name varchar(1024), line_num int, is_native boolean) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.threadStackEntries'; create or replace function system_info() returns table( source_name varchar(128), item_name varchar(1024), item_units varchar(128), item_value varchar(65535)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.systemInfo'; create or replace function performance_counters() returns table( source_name varchar(128), counter_name varchar(1024), counter_units varchar(128), counter_value varchar(1024)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.performanceCounters'; -- lie and say this is non-deterministic, since it's usually used -- in cases where it would be annoying if it got optimized away create or replace function sleep(millis bigint) returns integer language java no sql not deterministic external name 'class net.sf.farrago.syslib.FarragoManagementUDR.sleep'; -- flushes all entries from the global code cache create or replace procedure flush_code_cache() language java parameter style java reads sql data external name 'class net.sf.farrago.syslib.FarragoManagementUDR.flushCodeCache'; -- lets an administrator kill a running session -- TODO: grant this only to a privileged user create or replace procedure kill_session(in id bigint) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoKillUDR.killSession'; create or replace procedure kill_session(in id bigint, in cancel_only boolean) language java parameter style java no sql specific kill_session_cancel external name 'class net.sf.farrago.syslib.FarragoKillUDR.killSession'; -- lets an administrator kill an executing statement -- (like unix "kill -KILL") -- param ID: globally-unique statement id -- TODO: grant this only to a privileged user create or replace procedure kill_statement(in id bigint) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatement'; create or replace procedure kill_statement(in id bigint, in cancel_only boolean) language java parameter style java no sql specific kill_statement_cancel external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatement'; -- kills all statements with SQL matching a given string -- (like unix pkill) -- Works around lack of scalar subqueries, which makes kill_statement(id) hard to use -- param SQL: a string -- TODO: grant this only to a privileged user create or replace procedure kill_statement_match(in s varchar(256)) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatementMatch'; create or replace procedure kill_statement_match( in s varchar(256), in cancel_only boolean ) language java parameter style java no sql specific kill_statement_match_cancel external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatementMatch'; -- sets a filter on the optimizer rules to be used in the current session create or replace procedure set_opt_rule_desc_exclusion_filter( in regex varchar(2000)) language java contains sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.setOptRuleDescExclusionFilter'; -- exports the catalog to an XMI file create or replace procedure export_catalog_xmi(in filename varchar(65535)) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.exportCatalog'; -- exports query results to a delimited file (optionally with BCP control file) create or replace procedure export_query_to_file( in query_sql varchar(65535), in path_without_extension varchar(65535), in bcp boolean, in include_data boolean, in delete_failed_file boolean, in field_delimiter varchar(2), in file_extension varchar(5), in date_format varchar(128), in time_format varchar(128), in timestamp_format varchar(128)) language java reads sql data specific export_query_to_file_3 called on null input external name 'class net.sf.farrago.syslib.FarragoExportSchemaUDR.exportQueryToFile'; -- exports tables in a schema to a delimited file create or replace procedure export_schema_to_file( in cat varchar(128), in schma varchar(128), in exclude boolean, in tlist varchar(65535), in tpattern varchar(65535), in dir varchar(65535), in bcp boolean, in delete_failed_file boolean, in field_delimiter varchar(2), in file_extension varchar(5), in date_format varchar(50), in time_format varchar(50), in timestamp_format varchar(50)) language java reads sql data called on null input external name 'class net.sf.farrago.syslib.FarragoExportSchemaUDR.exportSchemaToFile'; -- switches default character set to Unicode create or replace procedure change_default_character_set_to_unicode() language java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.setUnicodeAsDefault'; -- Returns session parameters create or replace function session_parameters () returns table( param_name varchar(128), param_value varchar(128)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.sessionParameters'; create or replace view session_parameters_view as select * from table(session_parameters()); -- todo: grant this only to a privileged user grant select on session_parameters_view to public; -- -- Statistics -- -- Get the row count of a table create or replace function stat_get_row_count( catalog_name varchar(2000), schema_name varchar(2000), table_name varchar(2000)) returns bigint language java contains sql external name 'class net.sf.farrago.syslib.FarragoStatsUDR.get_row_count'; -- Set the row count of a table create or replace procedure stat_set_row_count( in catalog_name varchar(2000), in schema_name varchar(2000), in table_name varchar(2000), in row_count bigint) language java contains sql external name 'class net.sf.farrago.syslib.FarragoStatsUDR.set_row_count'; -- Set the page count of an index create or replace procedure stat_set_page_count( in catalog_name varchar(2000), in schema_name varchar(2000), in index_name varchar(2000), in page_count bigint) language java contains sql external name 'class net.sf.farrago.syslib.FarragoStatsUDR.set_page_count'; -- Generate a histogram for a column -- -- distribution_type must be 0 for now -- value_digits are characters to use for fake column values create or replace procedure stat_set_column_histogram( in catalog_name varchar(2000), in schema_name varchar(2000), in table_name varchar(2000), in column_name varchar(2000), in distict_values bigint, in sample_percent int, in sample_distinct_values bigint, in distribution_type int, in value_digits varchar(2000)) language java contains sql external name 'class net.sf.farrago.syslib.FarragoStatsUDR.set_column_histogram'; -- Get cardinality and selectivity for an expression. -- -- example expressions for an integer column (other types work as well, but -- note that there's no way to escape brackets or commas in this trivial -- implementation): -- '123' = 123 -- '[123' >= 123 -- '(123' > 123 -- '123]' <= 123 -- '[10,20)' >= 10 and < 20 create or replace function stat_get_cardinality( catalog_name varchar(2000), schema_name varchar(2000), table_name varchar(2000), column_name varchar(2000), expression varchar(2000)) returns double language java no sql external name 'class net.sf.farrago.syslib.FarragoStatsUDR.get_cardinality'; create or replace function stat_get_selectivity( catalog_name varchar(2000), schema_name varchar(2000), table_name varchar(2000), column_name varchar(2000), expression varchar(2000)) returns double language java no sql external name 'class net.sf.farrago.syslib.FarragoStatsUDR.get_selectivity'; -- Statistics views create or replace view page_counts_view as select i.table_cat, i.table_schem, i.table_name, i.index_name, i.pages from sys_boot.jdbc_metadata.index_info_internal i where i.pages is not null ; create or replace view row_counts_view as select t.table_cat, t.table_schem, t.table_name, acs."rowCount" as row_count from sys_boot.jdbc_metadata.tables_view_internal t inner join sys_fem."SQL2003"."AbstractColumnSet" acs on t."mofId" = acs."mofId" where acs."rowCount" is not null ; create or replace view histograms_view_internal as select c.table_cat, c.table_schem, c.table_name, c.column_name, h."distinctValueCount" as "CARDINALITY", h."distinctValueCountEstimated" as cardinality_estimated, h."percentageSampled" as percent_sampled, h."sampleSize" as sample_size, h."barCount" as bar_count, h."rowsPerBar" as rows_per_bar, h."rowsLastBar" as rows_last_bar, cast(h."analyzeTime" as timestamp) as last_analyze_time, h."mofId" from sys_boot.jdbc_metadata.columns_view_internal c inner join sys_fem.med."ColumnHistogram" h on c."mofId" = h."Column" where h."analyzeTime" = (select max("analyzeTime") from sys_fem.med."ColumnHistogram" where "Column" = h."Column") ; create or replace view histograms_view as select h.table_cat, h.table_schem, h.table_name, h.column_name, h."CARDINALITY", h.cardinality_estimated, h.percent_sampled, h.sample_size, h.bar_count, h.rows_per_bar, h.rows_last_bar, h.last_analyze_time from histograms_view_internal h ; create or replace view histogram_bars_view as select h.table_cat, h.table_schem, h.table_name, h.column_name, b."ordinal" as ordinal, b."startingValue" as start_value, b."valueCount" as value_count from histograms_view_internal h inner join sys_fem.med."ColumnHistogramBar" b on h."mofId" = b."Histogram" ; -- -- Sequences -- create or replace view sequences_view as select c.table_cat, c.table_schem, c.table_name, c.column_name, s."baseValue", s."increment", s."minValue", s."maxValue", s."cycle", s."expired" from sys_boot.jdbc_metadata.columns_view_internal c inner join sys_fem."SQL2003"."SequenceGenerator" s on c."mofId" = s."Column" ; -- -- Database admin internal views and functions -- create or replace function get_table_type_by_mof_class_name( mofclassname varchar(128)) returns varchar(128) contains sql deterministic return case when mofclassname='LocalView' then 'LOCAL VIEW' when mofclassname='LocalTable' then 'LOCAL TABLE' when mofclassname='ForeignTable' then 'FOREIGN TABLE' else cast(mofclassname as varchar(128)) end; create or replace view dba_schemas_internal1 as select cast(c."name" as varchar(128)) as catalog_name, cast(s."name" as varchar(128)) as schema_name, cast(s."creationTimestamp" as timestamp) as creation_timestamp, cast(s."modificationTimestamp" as timestamp) as last_modified_timestamp, cast(s."description" as varchar(65535)) as remarks, s."mofId", s."lineageId" from sys_fem."SQL2003"."LocalCatalog" c inner join sys_fem."SQL2003"."LocalSchema" s on c."mofId" = s."namespace" ; create or replace view dba_schemas_internal2 as select catalog_name, schema_name, creation_timestamp, last_modified_timestamp, remarks, si."mofId", si."lineageId", g."Grantee" from dba_schemas_internal1 si inner join sys_fem."Security"."Grant" g on si."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace view dba_tables_internal1 as select cast(table_cat as varchar(128)) as catalog_name, cast(table_schem as varchar(128)) as schema_name, cast(table_name as varchar(128)) as table_name, sys_boot.mgmt.get_table_type_by_mof_class_name(t."mofClassName") as table_type, cast(ae."creationTimestamp" as timestamp) as creation_timestamp, cast(ae."modificationTimestamp" as timestamp) as last_modification_timestamp, cast("description" as varchar(128)) as remarks, ae."mofId", ae."lineageId" from sys_boot.jdbc_metadata.tables_view_internal t inner join sys_fem."SQL2003"."AnnotatedElement" ae on t."mofId" = ae."mofId" ; create or replace view dba_tables_internal2 as select catalog_name, schema_name, table_name, table_type, creation_timestamp, last_modification_timestamp, remarks, g."Grantee", dti."mofId", dti."lineageId" from dba_tables_internal1 dti inner join sys_fem."Security"."Grant" g on dti."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace view dba_views_internal1 as select cast(object_catalog as varchar(128)) as catalog_name, cast(object_schema as varchar(128)) as schema_name, cast(v."name" as varchar(128)) as view_name, cast("creationTimestamp" as timestamp) as creation_timestamp, cast("modificationTimestamp" as timestamp) as last_modification_timestamp, cast("originalDefinition" as varchar(65535)) as original_text, cast("description" as varchar(65535)) as remarks, v."mofId", v."lineageId" from sys_boot.jdbc_metadata.schemas_view_internal s inner join sys_fem."SQL2003"."LocalView" v on s."mofId" = v."namespace" ; create or replace view dba_views_internal2 as select catalog_name, schema_name, view_name, creation_timestamp, last_modification_timestamp, original_text, remarks, vi."mofId", vi."lineageId", g."Grantee" from dba_views_internal1 vi inner join sys_fem."Security"."Grant" g on vi."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace view dba_stored_tables_internal1 as select cast(object_catalog as varchar(128)) as catalog_name, cast(object_schema as varchar(128)) as schema_name, cast(t."name" as varchar(128)) as table_name, cast(t."creationTimestamp" as timestamp) as creation_timestamp, cast(t."modificationTimestamp" as timestamp) as last_modification_timestamp, t."lastAnalyzeRowCount" as last_analyze_row_count, cast(t."analyzeTime" as timestamp) as last_analyze_timestamp, t."rowCount" as current_row_count, t."deletedRowCount" as deleted_row_count, cast(t."description" as varchar(65535))as remarks, t."lineageId", t."mofId" from sys_boot.jdbc_metadata.schemas_view_internal s inner join sys_fem.med."StoredTable" t on s."mofId" = t."namespace" ; create or replace view dba_stored_tables_internal2 as select catalog_name, schema_name, table_name, creation_timestamp, last_modification_timestamp, last_analyze_row_count, last_analyze_timestamp, current_row_count, deleted_row_count, remarks, sti."lineageId", sti."mofId", g."Grantee" from dba_stored_tables_internal1 sti inner join sys_fem."Security"."Grant" g on sti."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace view dba_routines_internal1 as select cast(s.object_catalog as varchar(128)) as catalog_name, cast(s.object_schema as varchar(128)) as schema_name, cast(r."invocationName" as varchar(128)) as invocation_name, cast(r."name" as varchar(128)) as specific_name, cast(r."externalName" as varchar(65535)) as external_name, upper(r."type") as routine_type, cast(r."creationTimestamp" as timestamp) as creation_timestamp, cast(r."modificationTimestamp" as timestamp) as last_modified_timestamp, r."isUdx" as is_table_function, cast(r."parameterStyle" as varchar(128)) as parameter_style, r."deterministic" as is_deterministic, cast(r."dataAccess" as varchar(128)) as data_access, cast(r."description" as varchar(65535)) as remarks, r."mofId", r."lineageId" from sys_boot.jdbc_metadata.schemas_view_internal s inner join sys_fem."SQL2003"."Routine" r on s."mofId" = r."namespace" ; create or replace view dba_routines_internal2 as select catalog_name, schema_name, invocation_name, specific_name, external_name, routine_type, creation_timestamp, last_modified_timestamp, is_table_function, parameter_style, is_deterministic, data_access, remarks, ri."mofId", ri."lineageId", g."Grantee" from dba_routines_internal1 ri inner join sys_fem."Security"."Grant" g on ri."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace view dba_routine_parameters_internal1 as select catalog_name, schema_name, specific_name as routine_specific_name, cast(rp."name" as varchar(128)) as parameter_name, rp."ordinal" as ordinal, coalesce(rp."length", rp."precision") as "PRECISION", rp."scale" as dec_digits, cast(rp."description" as varchar(65535)) as remarks, rp."mofId", rp."lineageId", rp."type", ri.is_table_function, ri.routine_type from dba_routines_internal1 ri inner join sys_fem."SQL2003"."RoutineParameter" rp on ri."mofId" = rp."behavioralFeature" ; create or replace view dba_foreign_wrappers_internal as select cast(dw."name" as varchar(128)) as foreign_wrapper_name, cast(dw."libraryFile" as varchar(65535)) as library, cast(dw."language" as varchar(128)) as "LANGUAGE", cast(dw."creationTimestamp" as timestamp) as creation_timestamp, cast(dw."modificationTimestamp" as timestamp) last_modified_timestamp, cast(dw."description" as varchar(65535)) as remarks, g."Grantee", dw."mofId", dw."lineageId" from sys_fem.med."DataWrapper" dw inner join sys_fem."Security"."Grant" g on dw."mofId" = g."Element" where dw."foreign" = true and g."action" = 'CREATION' ; create or replace view dba_foreign_servers_internal1 as select foreign_wrapper_name, cast(ds."name" as varchar(128)) as foreign_server_name, cast(ds."creationTimestamp" as timestamp) as creation_timestamp, cast(ds."modificationTimestamp" as timestamp) as last_modified_timestamp, cast(ds."description" as varchar(65535)) as remarks, ds."mofId", ds."lineageId" from dba_foreign_wrappers_internal fwi inner join sys_fem.med."DataServer" ds on fwi."mofId" = ds."Wrapper" ; create or replace view dba_foreign_servers_internal2 as select foreign_wrapper_name, foreign_server_name, creation_timestamp, last_modified_timestamp, remarks, g."Grantee", fsi."mofId", fsi."lineageId" from dba_foreign_servers_internal1 fsi inner join sys_fem."Security"."Grant" g on fsi."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace view dba_foreign_tables_internal1 as select fs.foreign_wrapper_name, fs.foreign_server_name, cast(ft."name" as varchar(128))as foreign_table_name, cast(ft."creationTimestamp" as timestamp) as creation_timestamp, cast(ft."modificationTimestamp" as timestamp) as last_modified_timestamp, ft."lastAnalyzeRowCount" as last_analyze_row_count, cast(ft."analyzeTime" as timestamp) as last_analyze_timestamp, cast(ft."description" as varchar(65535)) as remarks, ft."mofId", ft."lineageId" from dba_foreign_servers_internal1 fs inner join sys_fem.med."ForeignTable" ft on fs."mofId" = ft."Server" ; create or replace view dba_foreign_tables_internal2 as select fti.foreign_wrapper_name, fti.foreign_server_name, fti.foreign_table_name, fti.creation_timestamp, fti.last_modified_timestamp, fti.last_analyze_row_count, fti.last_analyze_timestamp, fti.remarks, g."Grantee", fti."mofId", fti."lineageId" from dba_foreign_tables_internal1 fti inner join sys_fem."Security"."Grant" g on fti."mofId" = g."Element" where g."action" = 'CREATION' ; -- Returns the set of all foreign data wrappers which have been marked -- as suitable for browse connect (mark is via the presence of the -- BROWSE_CONNECT_DESCRIPTION option). create or replace view browse_connect_foreign_wrappers as select dw."name" as foreign_wrapper_name, so."value" as browse_connect_description from sys_fem.med."DataWrapper" dw inner join sys_fem.med."StorageOption" so on dw."mofId" = so."StoredElement" where dw."foreign" = true and so."name" = 'BROWSE_CONNECT_DESCRIPTION' ; create or replace view dba_labels_internal as select cast(lbl."name" as varchar(128)) as label_name, cast(pLbl."name" as varchar(128)) as parent_label_name, lbl."commitSequenceNumber" as csn, cast(lbl."creationTimestamp" as timestamp) as creation_timestamp, cast(lbl."modificationTimestamp" as timestamp) last_modified_timestamp, cast(lbl."description" as varchar(65535)) as remarks, lbl."mofId", lbl."lineageId", g."Grantee" from sys_fem.med."Label" lbl left outer join sys_fem.med."Label" pLbl on lbl."ParentLabel" = pLbl."mofId" inner join sys_fem."Security"."Grant" g on lbl."mofId" = g."Element" where g."action" = 'CREATION' ; create or replace procedure create_directory( directory_path varchar(1024)) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.createDirectory'; create or replace procedure delete_file_or_directory( file_path varchar(1024)) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.deleteFileOrDirectory'; -- Tests that a connection can be established to a particular -- SQL/MED local or foreign data server. create or replace procedure test_data_server( server_name varchar(128)) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoMedUDR.testServer'; -- Tests that a connection can be established for all SQL/MED servers -- instantiated from a particular data wrapper. create or replace procedure test_all_servers_for_wrapper( wrapper_name varchar(128)) language java parameter style java no sql external name 'class net.sf.farrago.syslib.FarragoMedUDR.testAllServersForWrapper'; -- Returns the set of options relevant to a given wrapper. A partial -- set of options may be passed in via the proposed_server_options -- cursor parameter, which must have two columns (OPTION_NAME and -- OPTION_VALUE, in that order). This allows for an incremental -- connection interaction, starting with specifying no options, then -- some, then more, stopping once user and wrapper are both satisfied. -- The result set is not fully normalized, because some options -- support a list of choices (e.g. for a dropdown selection UI -- widget). optional_choice_ordinal -1 represents the "current" -- choice (either proposed by the user or chosen as default by the -- wrapper); other choice ordinals starting from 0 represent possible -- choices (if known). create or replace function browse_connect_foreign_server( foreign_wrapper_name varchar(128), proposed_server_options cursor) returns table( option_ordinal integer, option_name varchar(128), option_description varchar(4096), is_option_required boolean, option_choice_ordinal int, option_choice_value varchar(4096)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoMedUDR.browseConnectServer'; -- A view which can be used as the input cursor for proposed_server_options -- when no options are set (initial browse). create or replace view browse_connect_empty_options as select '' as option_name, '' as option_value from sys_boot.jdbc_metadata.empty_view; -- Returns foreign schemas accessible via a given foreign server. create or replace function browse_foreign_schemas( foreign_server_name varchar(128)) returns table( schema_name varchar(128), description varchar(4096)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoMedUDR.browseForeignSchemas'; -- -- Datetime conversion functions -- -- converts a string to a date, according to the specified format string create or replace function char_to_date(format varchar(50), dateString varchar(128)) returns date language java specific std_char_to_date no sql external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.char_to_date'; create or replace function char_to_time(format varchar(50), timeString varchar(128)) returns time language java specific std_char_to_time no sql external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.char_to_time'; create or replace function char_to_timestamp( format varchar(50), timestampString varchar(128)) returns timestamp language java specific std_char_to_timestamp no sql external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.char_to_timestamp'; -- formats a string as a date, according to the specified format string create or replace function date_to_char(format varchar(50), d date) returns varchar(128) language java specific std_date_to_char no sql external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.date_to_char'; create or replace function time_to_char(format varchar(50), t time) returns varchar(128) language java specific std_time_to_char no sql external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.time_to_char'; create or replace function timestamp_to_char(format varchar(50), ts timestamp) returns varchar(128) language java specific std_timestamp_to_char no sql external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.timestamp_to_char'; create or replace function perforce_changelists( file_pattern varchar(2048), maxChanges integer) returns table( changelist_number varchar(128), changelist_date varchar(128), submitter varchar(128), perforce_client varchar(128), change_description varchar(2048)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoPerforceUDR.getChangelists'; create or replace view perforce_submitters as select distinct submitter from table(perforce_changelists('.../dev/f...', -1)); -- retrieves a long catalog string attribute in chunks create or replace function repository_lob_text( mof_id varchar(128), attribute_name varchar(128)) returns table( chunk_offset integer, chunk_text varchar(1024)) language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoManagementUDR.lobText'; -- variation of LucidDB session personality but with index only scans enabled create or replace jar sys_boot.sys_boot.luciddb_index_only_plugin library 'class com.lucidera.farrago.LucidDbIndexOnlySessionFactory' options(0); eigenbase-farrago-0.9.0/initsql/configFennelHandleTracing.ref0000444000175000017500000000045011173714170024156 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/configFennelHandleTracing.ref#4 $ > -- This configures Farrago to write a Fennel JNI handle trace to a file > -- fennel.handles in the working directory in which Farrago is started. > > alter system set "jniHandleTraceFile" = 'fennel.handles'; > > > !quit eigenbase-farrago-0.9.0/initsql/createSalesSchema.sql0000444000175000017500000000512311173714170022536 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/createSalesSchema.sql#15 $ -- This script creates a simple schema used by some of the unit tests. !set verbose true -- create local sales schema create schema sales; set schema 'sales'; create table depts( deptno integer not null primary key, name varchar(128) not null constraint depts_unique_name unique); create table emps( empno integer not null, name varchar(128) not null, deptno integer not null, gender char(1) default 'M', city varchar(128), empid integer not null unique, age integer, public_key varbinary(50), slacker boolean, manager boolean not null, primary key(deptno,empno)) create index emps_ux on emps(name); create global temporary table temps( empno integer not null, name varchar(128) not null, deptno integer not null, gender char(1), city varchar(128), empid integer default 999 not null, age integer, public_key varbinary(50), slacker boolean, manager boolean not null, primary key(deptno,empno)) on commit delete rows create clustered index temps_cx on temps(empno); create view empsview as select empno, name from emps; create view tempsview as select empno, name from temps; create view joinview as select depts.name as dname,emps.name as ename from emps inner join depts on emps.deptno=depts.deptno; create function decrypt_public_key(k varbinary(50)) returns varchar(25) language java no sql external name 'class net.sf.farrago.test.FarragoTestUDR.decryptPublicKey'; create function maybe_female(gender char(1)) returns boolean contains sql return not((gender = 'F') is false); insert into depts values (10,trim('Sales')), (20,'Marketing'), (30,'Accounts'); insert into emps values (100,'Fred',10,null,null,30,25, x'41626320',true,false), (110,trim('Eric'),20,'M',trim('San Francisco'),3,80,x'416263',null,false), (110,'John',40,'M','Vancouver',2,null,x'58797A',false,true), (120,'Wilma',20,'F',null,1,50,null,null,true); -- define foreign server for hsqldb sample data create server hsqldb_demo foreign data wrapper sys_jdbc options( driver_class 'org.hsqldb.jdbcDriver', url 'jdbc:hsqldb:testcases/hsqldb/scott', user_name 'SA', table_types 'TABLE,VIEW'); -- create Volcano personality "jar" for use by tests that need it create jar sys_boot.sys_boot.volcano_plugin library 'class net.sf.farrago.defimpl.FarragoVolcanoPersonalityFactory' options(0); -- likewise for LucidDB session personality create jar sys_boot.sys_boot.luciddb_plugin library 'class com.lucidera.farrago.LucidDbSessionFactory' options(0); eigenbase-farrago-0.9.0/initsql/createSqljSchema.ref0000444000175000017500000000205511173714170022356 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/createSqljSchema.ref#9 $ > -- This script creates the SQLJ support schema > > !set verbose true > > set catalog 'localdb'; > create or replace schema sqlj; > > set schema 'sqlj'; > > create or replace procedure install_jar( > in url varchar(2000), > in jar varchar(2000), > in deploy integer) > language java > modifies sql data > external name 'class net.sf.farrago.ddl.DdlSqlj.install_jar'; > > create or replace procedure replace_jar( > in url varchar(2000), > in jar varchar(2000)) > language java > modifies sql data > external name 'class net.sf.farrago.ddl.DdlSqlj.replace_jar'; > > create or replace procedure remove_jar( > in jar varchar(2000), > in undeploy integer) > language java > modifies sql data > external name 'class net.sf.farrago.ddl.DdlSqlj.remove_jar'; > > create or replace procedure alter_java_path( > in jar varchar(2000), > in path varchar(2000)) > language java > modifies sql data > external name 'class net.sf.farrago.ddl.DdlSqlj.alter_java_path'; > > !quit eigenbase-farrago-0.9.0/initsql/createSqljSchema.sql0000444000175000017500000000172611173714170022405 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/createSqljSchema.sql#6 $ -- This script creates the SQLJ support schema !set verbose true set catalog 'localdb'; create or replace schema sqlj; set schema 'sqlj'; create or replace procedure install_jar( in url varchar(2000), in jar varchar(2000), in deploy integer) language java modifies sql data external name 'class net.sf.farrago.ddl.DdlSqlj.install_jar'; create or replace procedure replace_jar( in url varchar(2000), in jar varchar(2000)) language java modifies sql data external name 'class net.sf.farrago.ddl.DdlSqlj.replace_jar'; create or replace procedure remove_jar( in jar varchar(2000), in undeploy integer) language java modifies sql data external name 'class net.sf.farrago.ddl.DdlSqlj.remove_jar'; create or replace procedure alter_java_path( in jar varchar(2000), in path varchar(2000)) language java modifies sql data external name 'class net.sf.farrago.ddl.DdlSqlj.alter_java_path'; eigenbase-farrago-0.9.0/initsql/configFennelHandleTracing.sql0000444000175000017500000000042111173714170024177 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/configFennelHandleTracing.sql#1 $ -- This configures Farrago to write a Fennel JNI handle trace to a file -- fennel.handles in the working directory in which Farrago is started. alter system set "jniHandleTraceFile" = 'fennel.handles'; eigenbase-farrago-0.9.0/initsql/createSalesSchema.ref0000444000175000017500000000543011173714170022514 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/createSalesSchema.ref#19 $ > -- This script creates a simple schema used by some of the unit tests. > > !set verbose true > > -- create local sales schema > create schema sales; > set schema 'sales'; > > create table depts( > deptno integer not null primary key, > name varchar(128) not null constraint depts_unique_name unique); > > create table emps( > empno integer not null, > name varchar(128) not null, > deptno integer not null, > gender char(1) default 'M', > city varchar(128), > empid integer not null unique, > age integer, > public_key varbinary(50), > slacker boolean, > manager boolean not null, > primary key(deptno,empno)) > create index emps_ux on emps(name); > > create global temporary table temps( > empno integer not null, > name varchar(128) not null, > deptno integer not null, > gender char(1), > city varchar(128), > empid integer default 999 not null, > age integer, > public_key varbinary(50), > slacker boolean, > manager boolean not null, > primary key(deptno,empno)) on commit delete rows > create clustered index temps_cx on temps(empno); > > create view empsview as > select empno, name from emps; > > create view tempsview as > select empno, name from temps; > > create view joinview as > select depts.name as dname,emps.name as ename > from emps inner join depts > on emps.deptno=depts.deptno; > > create function decrypt_public_key(k varbinary(50)) > returns varchar(25) > language java > no sql > external name 'class net.sf.farrago.test.FarragoTestUDR.decryptPublicKey'; > > create function maybe_female(gender char(1)) > returns boolean > contains sql > return not((gender = 'F') is false); > > insert into depts values > (10,trim('Sales')), > (20,'Marketing'), > (30,'Accounts'); > > insert into emps values > (100,'Fred',10,null,null,30,25, x'41626320',true,false), > (110,trim('Eric'),20,'M',trim('San Francisco'),3,80,x'416263',null,false), > (110,'John',40,'M','Vancouver',2,null,x'58797A',false,true), > (120,'Wilma',20,'F',null,1,50,null,null,true); > > -- define foreign server for hsqldb sample data > create server hsqldb_demo > foreign data wrapper sys_jdbc > options( > driver_class 'org.hsqldb.jdbcDriver', > url 'jdbc:hsqldb:testcases/hsqldb/scott', > user_name 'SA', > table_types 'TABLE,VIEW'); > > -- create Volcano personality "jar" for use by tests that need it > create jar sys_boot.sys_boot.volcano_plugin > library 'class net.sf.farrago.defimpl.FarragoVolcanoPersonalityFactory' > options(0); > > -- likewise for LucidDB session personality > create jar sys_boot.sys_boot.luciddb_plugin > library 'class com.lucidera.farrago.LucidDbSessionFactory' > options(0); > > > !quit eigenbase-farrago-0.9.0/initsql/createMgmtViews.ref0000444000175000017500000010017611173714170022251 0ustar drazzibdrazzib> -- This script creates a view schema used for database management > > !set verbose true > > -- create views in system-owned schema sys_boot.mgmt > create or replace schema sys_boot.mgmt; > set schema 'sys_boot.mgmt'; > set path 'sys_boot.mgmt'; > > create or replace function repository_properties() > returns table(property_name varchar(255), property_value varchar(255)) > language java > parameter style system defined java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.repositoryProperties'; > > create or replace view repository_properties_view as > select * from table(repository_properties()); > > create or replace function repository_integrity_violations() > returns table(description varchar(65535), mof_id varchar(128)) > language java > parameter style system defined java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.repositoryIntegrityViolations'; > > create or replace function statements() > returns table(id bigint, session_id bigint, sql_stmt varchar(1024), create_time timestamp, parameters varchar(1024)) > language java > parameter style system defined java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.statements'; > > create or replace view statements_view as > select * from table(statements()); > > -- todo: grant this only to a privileged user > grant select on statements_view to public; > > create or replace function sessions() > returns table(id int, url varchar(128), current_user_name varchar(128), current_role_name varchar(128), session_user_name varchar(128), system_user_name varchar(128), system_user_fullname varchar(128), session_name varchar(128), program_name varchar(128), process_id int, catalog_name varchar(128), schema_name varchar(128), is_closed boolean, is_auto_commit boolean, is_txn_in_progress boolean, label_name varchar(128)) > language java > parameter style system defined java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.sessions'; > > create or replace view sessions_view as > select * from table(sessions()); > > -- todo: grant this only to a privileged user > grant select on sessions_view to public; > > create or replace function objects_in_use() > returns table(session_id bigint, stmt_id bigint, mof_id varchar(128)) > language java > parameter style system defined java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.objectsInUse'; > > create or replace view objects_in_use_view as > select * from table(objects_in_use()); > > -- TODO: grant this only to a privileged user > grant select on objects_in_use_view to public; > > create or replace function threads() > returns table( > thread_id bigint, thread_group_name varchar(128), thread_name varchar(128), > thread_priority int, thread_state varchar(128), is_alive boolean, > is_daemon boolean, is_interrupted boolean) > language java > parameter style system defined java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.threadList'; > > create or replace function thread_stack_entries() > returns table( > thread_id bigint, stack_level int, entry_string varchar(1024), > class_name varchar(128), method_name varchar(128), > file_name varchar(1024), line_num int, is_native boolean) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.threadStackEntries'; > > create or replace function system_info() > returns table( > source_name varchar(128), > item_name varchar(1024), > item_units varchar(128), > item_value varchar(65535)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.systemInfo'; > > create or replace function performance_counters() > returns table( > source_name varchar(128), > counter_name varchar(1024), > counter_units varchar(128), > counter_value varchar(1024)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.performanceCounters'; > > -- lie and say this is non-deterministic, since it's usually used > -- in cases where it would be annoying if it got optimized away > create or replace function sleep(millis bigint) > returns integer > language java > no sql > not deterministic > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.sleep'; > > -- flushes all entries from the global code cache > create or replace procedure flush_code_cache() > language java > parameter style java > reads sql data > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.flushCodeCache'; > > -- lets an administrator kill a running session > -- TODO: grant this only to a privileged user > create or replace procedure kill_session(in id bigint) > language java > parameter style java > no sql > external name 'class net.sf.farrago.syslib.FarragoKillUDR.killSession'; > > create or replace procedure kill_session(in id bigint, in cancel_only boolean) > language java > parameter style java > no sql > specific kill_session_cancel > external name 'class net.sf.farrago.syslib.FarragoKillUDR.killSession'; > > -- lets an administrator kill an executing statement > -- (like unix "kill -KILL") > -- param ID: globally-unique statement id > -- TODO: grant this only to a privileged user > create or replace procedure kill_statement(in id bigint) > language java > parameter style java > no sql > external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatement'; > > create or replace procedure kill_statement(in id bigint, in cancel_only boolean) > language java > parameter style java > no sql > specific kill_statement_cancel > external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatement'; > > -- kills all statements with SQL matching a given string > -- (like unix pkill) > -- Works around lack of scalar subqueries, which makes kill_statement(id) hard to use > -- param SQL: a string > -- TODO: grant this only to a privileged user > create or replace procedure kill_statement_match(in s varchar(256)) > language java > parameter style java > no sql > external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatementMatch'; > > create or replace procedure kill_statement_match( > in s varchar(256), in cancel_only boolean ) > language java > parameter style java > no sql > specific kill_statement_match_cancel > external name 'class net.sf.farrago.syslib.FarragoKillUDR.killStatementMatch'; > > -- sets a filter on the optimizer rules to be used in the current session > create or replace procedure set_opt_rule_desc_exclusion_filter( > in regex varchar(2000)) > language java > contains sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.setOptRuleDescExclusionFilter'; > > -- exports the catalog to an XMI file > create or replace procedure export_catalog_xmi(in filename varchar(65535)) > language java > parameter style java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.exportCatalog'; > > -- exports query results to a delimited file (optionally with BCP control file) > create or replace procedure export_query_to_file( > in query_sql varchar(65535), > in path_without_extension varchar(65535), > in bcp boolean, > in include_data boolean, > in delete_failed_file boolean, > in field_delimiter varchar(2), > in file_extension varchar(5), > in date_format varchar(128), > in time_format varchar(128), > in timestamp_format varchar(128)) > language java > reads sql data > specific export_query_to_file_3 > called on null input > external name 'class net.sf.farrago.syslib.FarragoExportSchemaUDR.exportQueryToFile'; > > -- exports tables in a schema to a delimited file > create or replace procedure export_schema_to_file( > in cat varchar(128), > in schma varchar(128), > in exclude boolean, > in tlist varchar(65535), > in tpattern varchar(65535), > in dir varchar(65535), > in bcp boolean, > in delete_failed_file boolean, > in field_delimiter varchar(2), > in file_extension varchar(5), > in date_format varchar(50), > in time_format varchar(50), > in timestamp_format varchar(50)) > language java > reads sql data > called on null input > external name 'class net.sf.farrago.syslib.FarragoExportSchemaUDR.exportSchemaToFile'; > > -- switches default character set to Unicode > create or replace procedure change_default_character_set_to_unicode() > language java > no sql > external name 'class net.sf.farrago.syslib.FarragoManagementUDR.setUnicodeAsDefault'; > > -- Returns session parameters > create or replace function session_parameters () > returns table( > param_name varchar(128), > param_value varchar(128)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.sessionParameters'; > > create or replace view session_parameters_view as > select * from table(session_parameters()); > > -- todo: grant this only to a privileged user > grant select on session_parameters_view to public; > > -- > -- Statistics > -- > > -- Get the row count of a table > create or replace function stat_get_row_count( > catalog_name varchar(2000), > schema_name varchar(2000), > table_name varchar(2000)) > returns bigint > language java > contains sql > external name 'class net.sf.farrago.syslib.FarragoStatsUDR.get_row_count'; > > -- Set the row count of a table > create or replace procedure stat_set_row_count( > in catalog_name varchar(2000), > in schema_name varchar(2000), > in table_name varchar(2000), > in row_count bigint) > language java > contains sql > external name 'class net.sf.farrago.syslib.FarragoStatsUDR.set_row_count'; > > -- Set the page count of an index > create or replace procedure stat_set_page_count( > in catalog_name varchar(2000), > in schema_name varchar(2000), > in index_name varchar(2000), > in page_count bigint) > language java > contains sql > external name 'class net.sf.farrago.syslib.FarragoStatsUDR.set_page_count'; > > -- Generate a histogram for a column > -- > -- distribution_type must be 0 for now > -- value_digits are characters to use for fake column values > create or replace procedure stat_set_column_histogram( > in catalog_name varchar(2000), > in schema_name varchar(2000), > in table_name varchar(2000), > in column_name varchar(2000), > in distict_values bigint, > in sample_percent int, > in sample_distinct_values bigint, > in distribution_type int, > in value_digits varchar(2000)) > language java > contains sql > external name 'class net.sf.farrago.syslib.FarragoStatsUDR.set_column_histogram'; > > -- Get cardinality and selectivity for an expression. > -- > -- example expressions for an integer column (other types work as well, but > -- note that there's no way to escape brackets or commas in this trivial > -- implementation): > -- '123' = 123 > -- '[123' >= 123 > -- '(123' > 123 > -- '123]' <= 123 > -- '[10,20)' >= 10 and < 20 > create or replace function stat_get_cardinality( > catalog_name varchar(2000), > schema_name varchar(2000), > table_name varchar(2000), > column_name varchar(2000), > expression varchar(2000)) > returns double > language java > no sql > external name 'class net.sf.farrago.syslib.FarragoStatsUDR.get_cardinality'; > > create or replace function stat_get_selectivity( > catalog_name varchar(2000), > schema_name varchar(2000), > table_name varchar(2000), > column_name varchar(2000), > expression varchar(2000)) > returns double > language java > no sql > external name 'class net.sf.farrago.syslib.FarragoStatsUDR.get_selectivity'; > > -- Statistics views > create or replace view page_counts_view as > select > i.table_cat, > i.table_schem, > i.table_name, > i.index_name, > i.pages > from > sys_boot.jdbc_metadata.index_info_internal i > where > i.pages is not null > ; > > create or replace view row_counts_view as > select > t.table_cat, > t.table_schem, > t.table_name, > acs."rowCount" as row_count > from > sys_boot.jdbc_metadata.tables_view_internal t > inner join > sys_fem."SQL2003"."AbstractColumnSet" acs > on > t."mofId" = acs."mofId" > where > acs."rowCount" is not null > ; > > create or replace view histograms_view_internal as > select > c.table_cat, > c.table_schem, > c.table_name, > c.column_name, > h."distinctValueCount" as "CARDINALITY", > h."distinctValueCountEstimated" as cardinality_estimated, > h."percentageSampled" as percent_sampled, > h."sampleSize" as sample_size, > h."barCount" as bar_count, > h."rowsPerBar" as rows_per_bar, > h."rowsLastBar" as rows_last_bar, > cast(h."analyzeTime" as timestamp) as last_analyze_time, > h."mofId" > from > sys_boot.jdbc_metadata.columns_view_internal c > inner join > sys_fem.med."ColumnHistogram" h > on > c."mofId" = h."Column" > where > h."analyzeTime" = > (select max("analyzeTime") from sys_fem.med."ColumnHistogram" > where "Column" = h."Column") > ; > > create or replace view histograms_view as > select > h.table_cat, > h.table_schem, > h.table_name, > h.column_name, > h."CARDINALITY", > h.cardinality_estimated, > h.percent_sampled, > h.sample_size, > h.bar_count, > h.rows_per_bar, > h.rows_last_bar, > h.last_analyze_time > from > histograms_view_internal h > ; > > create or replace view histogram_bars_view as > select > h.table_cat, > h.table_schem, > h.table_name, > h.column_name, > b."ordinal" as ordinal, > b."startingValue" as start_value, > b."valueCount" as value_count > from > histograms_view_internal h > inner join > sys_fem.med."ColumnHistogramBar" b > on > h."mofId" = b."Histogram" > ; > > -- > -- Sequences > -- > > create or replace view sequences_view as > select > c.table_cat, > c.table_schem, > c.table_name, > c.column_name, > s."baseValue", > s."increment", > s."minValue", > s."maxValue", > s."cycle", > s."expired" > from > sys_boot.jdbc_metadata.columns_view_internal c > inner join > sys_fem."SQL2003"."SequenceGenerator" s > on > c."mofId" = s."Column" > ; > > -- > -- Database admin internal views and functions > -- > > create or replace function get_table_type_by_mof_class_name( > mofclassname varchar(128)) > returns varchar(128) > contains sql > deterministic > return case > when mofclassname='LocalView' then 'LOCAL VIEW' > when mofclassname='LocalTable' then 'LOCAL TABLE' > when mofclassname='ForeignTable' then 'FOREIGN TABLE' > else cast(mofclassname as varchar(128)) > end; > > create or replace view dba_schemas_internal1 as > select > cast(c."name" as varchar(128)) as catalog_name, > cast(s."name" as varchar(128)) as schema_name, > cast(s."creationTimestamp" as timestamp) as creation_timestamp, > cast(s."modificationTimestamp" as timestamp) as last_modified_timestamp, > cast(s."description" as varchar(65535)) as remarks, > s."mofId", > s."lineageId" > from > sys_fem."SQL2003"."LocalCatalog" c > inner join > sys_fem."SQL2003"."LocalSchema" s > on > c."mofId" = s."namespace" > ; > > create or replace view dba_schemas_internal2 as > select > catalog_name, > schema_name, > creation_timestamp, > last_modified_timestamp, > remarks, > si."mofId", > si."lineageId", > g."Grantee" > from > dba_schemas_internal1 si > inner join > sys_fem."Security"."Grant" g > on > si."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > create or replace view dba_tables_internal1 as > select > cast(table_cat as varchar(128)) as catalog_name, > cast(table_schem as varchar(128)) as schema_name, > cast(table_name as varchar(128)) as table_name, > sys_boot.mgmt.get_table_type_by_mof_class_name(t."mofClassName") > as table_type, > cast(ae."creationTimestamp" as timestamp) as creation_timestamp, > cast(ae."modificationTimestamp" as timestamp) > as last_modification_timestamp, > cast("description" as varchar(128)) as remarks, > ae."mofId", > ae."lineageId" > from > sys_boot.jdbc_metadata.tables_view_internal t > inner join > sys_fem."SQL2003"."AnnotatedElement" ae > on > t."mofId" = ae."mofId" > ; > > create or replace view dba_tables_internal2 as > select > catalog_name, > schema_name, > table_name, > table_type, > creation_timestamp, > last_modification_timestamp, > remarks, > g."Grantee", > dti."mofId", > dti."lineageId" > from > dba_tables_internal1 dti > inner join > sys_fem."Security"."Grant" g > on > dti."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > create or replace view dba_views_internal1 as > select > cast(object_catalog as varchar(128)) as catalog_name, > cast(object_schema as varchar(128)) as schema_name, > cast(v."name" as varchar(128)) as view_name, > cast("creationTimestamp" as timestamp) as creation_timestamp, > cast("modificationTimestamp" as timestamp) as last_modification_timestamp, > cast("originalDefinition" as varchar(65535)) as original_text, > cast("description" as varchar(65535)) as remarks, > v."mofId", > v."lineageId" > from > sys_boot.jdbc_metadata.schemas_view_internal s > inner join > sys_fem."SQL2003"."LocalView" v > on > s."mofId" = v."namespace" > ; > > > create or replace view dba_views_internal2 as > select > catalog_name, > schema_name, > view_name, > creation_timestamp, > last_modification_timestamp, > original_text, > remarks, > vi."mofId", > vi."lineageId", > g."Grantee" > from > dba_views_internal1 vi > inner join > sys_fem."Security"."Grant" g > on > vi."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > create or replace view dba_stored_tables_internal1 as > select > cast(object_catalog as varchar(128)) as catalog_name, > cast(object_schema as varchar(128)) as schema_name, > cast(t."name" as varchar(128)) as table_name, > cast(t."creationTimestamp" as timestamp) as creation_timestamp, > cast(t."modificationTimestamp" as timestamp) > as last_modification_timestamp, > t."lastAnalyzeRowCount" as last_analyze_row_count, > cast(t."analyzeTime" as timestamp) as last_analyze_timestamp, > t."rowCount" as current_row_count, > t."deletedRowCount" as deleted_row_count, > cast(t."description" as varchar(65535))as remarks, > t."lineageId", > t."mofId" > from > sys_boot.jdbc_metadata.schemas_view_internal s > inner join > sys_fem.med."StoredTable" t > on > s."mofId" = t."namespace" > ; > > create or replace view dba_stored_tables_internal2 as > select > catalog_name, > schema_name, > table_name, > creation_timestamp, > last_modification_timestamp, > last_analyze_row_count, > last_analyze_timestamp, > current_row_count, > deleted_row_count, > remarks, > sti."lineageId", > sti."mofId", > g."Grantee" > from > dba_stored_tables_internal1 sti > inner join > sys_fem."Security"."Grant" g > on > sti."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > create or replace view dba_routines_internal1 as > select > cast(s.object_catalog as varchar(128)) as catalog_name, > cast(s.object_schema as varchar(128)) as schema_name, > cast(r."invocationName" as varchar(128)) as invocation_name, > cast(r."name" as varchar(128)) as specific_name, > cast(r."externalName" as varchar(65535)) as external_name, > upper(r."type") as routine_type, > cast(r."creationTimestamp" as timestamp) as creation_timestamp, > cast(r."modificationTimestamp" as timestamp) as last_modified_timestamp, > r."isUdx" as is_table_function, > cast(r."parameterStyle" as varchar(128)) as parameter_style, > r."deterministic" as is_deterministic, > cast(r."dataAccess" as varchar(128)) as data_access, > cast(r."description" as varchar(65535)) as remarks, > r."mofId", > r."lineageId" > from > sys_boot.jdbc_metadata.schemas_view_internal s > inner join > sys_fem."SQL2003"."Routine" r > on > s."mofId" = r."namespace" > ; > > create or replace view dba_routines_internal2 as > select > catalog_name, > schema_name, > invocation_name, > specific_name, > external_name, > routine_type, > creation_timestamp, > last_modified_timestamp, > is_table_function, > parameter_style, > is_deterministic, > data_access, > remarks, > ri."mofId", > ri."lineageId", > g."Grantee" > from > dba_routines_internal1 ri > inner join > sys_fem."Security"."Grant" g > on > ri."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > create or replace view dba_routine_parameters_internal1 as > select > catalog_name, > schema_name, > specific_name as routine_specific_name, > cast(rp."name" as varchar(128)) as parameter_name, > rp."ordinal" as ordinal, > coalesce(rp."length", rp."precision") as "PRECISION", > rp."scale" as dec_digits, > cast(rp."description" as varchar(65535)) as remarks, > rp."mofId", > rp."lineageId", > rp."type", > ri.is_table_function, > ri.routine_type > from > dba_routines_internal1 ri > inner join > sys_fem."SQL2003"."RoutineParameter" rp > on > ri."mofId" = rp."behavioralFeature" > ; > > create or replace view dba_foreign_wrappers_internal as > select > cast(dw."name" as varchar(128)) as foreign_wrapper_name, > cast(dw."libraryFile" as varchar(65535)) as library, > cast(dw."language" as varchar(128)) as "LANGUAGE", > cast(dw."creationTimestamp" as timestamp) as creation_timestamp, > cast(dw."modificationTimestamp" as timestamp) last_modified_timestamp, > cast(dw."description" as varchar(65535)) as remarks, > g."Grantee", > dw."mofId", > dw."lineageId" > from > sys_fem.med."DataWrapper" dw > inner join > sys_fem."Security"."Grant" g > on > dw."mofId" = g."Element" > where > dw."foreign" = true and g."action" = 'CREATION' > ; > > create or replace view dba_foreign_servers_internal1 as > select > foreign_wrapper_name, > cast(ds."name" as varchar(128)) as foreign_server_name, > cast(ds."creationTimestamp" as timestamp) as creation_timestamp, > cast(ds."modificationTimestamp" as timestamp) as last_modified_timestamp, > cast(ds."description" as varchar(65535)) as remarks, > ds."mofId", > ds."lineageId" > from > dba_foreign_wrappers_internal fwi > inner join > sys_fem.med."DataServer" ds > on > fwi."mofId" = ds."Wrapper" > ; > > create or replace view dba_foreign_servers_internal2 as > select > foreign_wrapper_name, > foreign_server_name, > creation_timestamp, > last_modified_timestamp, > remarks, > g."Grantee", > fsi."mofId", > fsi."lineageId" > from > dba_foreign_servers_internal1 fsi > inner join > sys_fem."Security"."Grant" g > on > fsi."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > create or replace view dba_foreign_tables_internal1 as > select > fs.foreign_wrapper_name, > fs.foreign_server_name, > cast(ft."name" as varchar(128))as foreign_table_name, > cast(ft."creationTimestamp" as timestamp) as creation_timestamp, > cast(ft."modificationTimestamp" as timestamp) as last_modified_timestamp, > ft."lastAnalyzeRowCount" as last_analyze_row_count, > cast(ft."analyzeTime" as timestamp) as last_analyze_timestamp, > cast(ft."description" as varchar(65535)) as remarks, > ft."mofId", > ft."lineageId" > from > dba_foreign_servers_internal1 fs > inner join > sys_fem.med."ForeignTable" ft > on > fs."mofId" = ft."Server" > ; > > create or replace view dba_foreign_tables_internal2 as > select > fti.foreign_wrapper_name, > fti.foreign_server_name, > fti.foreign_table_name, > fti.creation_timestamp, > fti.last_modified_timestamp, > fti.last_analyze_row_count, > fti.last_analyze_timestamp, > fti.remarks, > g."Grantee", > fti."mofId", > fti."lineageId" > from > dba_foreign_tables_internal1 fti > inner join > sys_fem."Security"."Grant" g > on > fti."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > -- Returns the set of all foreign data wrappers which have been marked > -- as suitable for browse connect (mark is via the presence of the > -- BROWSE_CONNECT_DESCRIPTION option). > create or replace view browse_connect_foreign_wrappers as > select > dw."name" as foreign_wrapper_name, > so."value" as browse_connect_description > from > sys_fem.med."DataWrapper" dw > inner join > sys_fem.med."StorageOption" so > on > dw."mofId" = so."StoredElement" > where > dw."foreign" = true > and so."name" = 'BROWSE_CONNECT_DESCRIPTION' > ; > > create or replace view dba_labels_internal as > select > cast(lbl."name" as varchar(128)) as label_name, > cast(pLbl."name" as varchar(128)) as parent_label_name, > lbl."commitSequenceNumber" as csn, > cast(lbl."creationTimestamp" as timestamp) as creation_timestamp, > cast(lbl."modificationTimestamp" as timestamp) last_modified_timestamp, > cast(lbl."description" as varchar(65535)) as remarks, > lbl."mofId", > lbl."lineageId", > g."Grantee" > from > sys_fem.med."Label" lbl > left outer join > sys_fem.med."Label" pLbl > on > lbl."ParentLabel" = pLbl."mofId" > inner join > sys_fem."Security"."Grant" g > on > lbl."mofId" = g."Element" > where > g."action" = 'CREATION' > ; > > > create or replace procedure create_directory( > directory_path varchar(1024)) > language java > parameter style java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.createDirectory'; > > create or replace procedure delete_file_or_directory( > file_path varchar(1024)) > language java > parameter style java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.deleteFileOrDirectory'; > > -- Tests that a connection can be established to a particular > -- SQL/MED local or foreign data server. > create or replace procedure test_data_server( > server_name varchar(128)) > language java > parameter style java > no sql > external name > 'class net.sf.farrago.syslib.FarragoMedUDR.testServer'; > > -- Tests that a connection can be established for all SQL/MED servers > -- instantiated from a particular data wrapper. > create or replace procedure test_all_servers_for_wrapper( > wrapper_name varchar(128)) > language java > parameter style java > no sql > external name > 'class net.sf.farrago.syslib.FarragoMedUDR.testAllServersForWrapper'; > > -- Returns the set of options relevant to a given wrapper. A partial > -- set of options may be passed in via the proposed_server_options > -- cursor parameter, which must have two columns (OPTION_NAME and > -- OPTION_VALUE, in that order). This allows for an incremental > -- connection interaction, starting with specifying no options, then > -- some, then more, stopping once user and wrapper are both satisfied. > -- The result set is not fully normalized, because some options > -- support a list of choices (e.g. for a dropdown selection UI > -- widget). optional_choice_ordinal -1 represents the "current" > -- choice (either proposed by the user or chosen as default by the > -- wrapper); other choice ordinals starting from 0 represent possible > -- choices (if known). > create or replace function browse_connect_foreign_server( > foreign_wrapper_name varchar(128), > proposed_server_options cursor) > returns table( > option_ordinal integer, > option_name varchar(128), > option_description varchar(4096), > is_option_required boolean, > option_choice_ordinal int, > option_choice_value varchar(4096)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoMedUDR.browseConnectServer'; > > -- A view which can be used as the input cursor for proposed_server_options > -- when no options are set (initial browse). > create or replace view browse_connect_empty_options as > select '' as option_name, '' as option_value > from sys_boot.jdbc_metadata.empty_view; > > -- Returns foreign schemas accessible via a given foreign server. > create or replace function browse_foreign_schemas( > foreign_server_name varchar(128)) > returns table( > schema_name varchar(128), > description varchar(4096)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoMedUDR.browseForeignSchemas'; > > -- > -- Datetime conversion functions > -- > > -- converts a string to a date, according to the specified format string > create or replace function char_to_date(format varchar(50), dateString varchar(128)) > returns date > language java > specific std_char_to_date > no sql > external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.char_to_date'; > > create or replace function char_to_time(format varchar(50), timeString varchar(128)) > returns time > language java > specific std_char_to_time > no sql > external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.char_to_time'; > > create or replace function char_to_timestamp( > format varchar(50), timestampString varchar(128)) > returns timestamp > language java > specific std_char_to_timestamp > no sql > external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.char_to_timestamp'; > > -- formats a string as a date, according to the specified format string > create or replace function date_to_char(format varchar(50), d date) > returns varchar(128) > language java > specific std_date_to_char > no sql > external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.date_to_char'; > > create or replace function time_to_char(format varchar(50), t time) > returns varchar(128) > language java > specific std_time_to_char > no sql > external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.time_to_char'; > > create or replace function timestamp_to_char(format varchar(50), ts timestamp) > returns varchar(128) > language java > specific std_timestamp_to_char > no sql > external name 'class net.sf.farrago.syslib.FarragoConvertDatetimeUDR.timestamp_to_char'; > > create or replace function perforce_changelists( > file_pattern varchar(2048), > maxChanges integer) > returns table( > changelist_number varchar(128), > changelist_date varchar(128), > submitter varchar(128), > perforce_client varchar(128), > change_description varchar(2048)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoPerforceUDR.getChangelists'; > > create or replace view perforce_submitters as > select distinct submitter > from table(perforce_changelists('.../dev/f...', -1)); > > -- retrieves a long catalog string attribute in chunks > create or replace function repository_lob_text( > mof_id varchar(128), > attribute_name varchar(128)) > returns table( > chunk_offset integer, > chunk_text varchar(1024)) > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoManagementUDR.lobText'; > > -- variation of LucidDB session personality but with index only scans enabled > create or replace jar sys_boot.sys_boot.luciddb_index_only_plugin > library 'class com.lucidera.farrago.LucidDbIndexOnlySessionFactory' > options(0); > > !quit eigenbase-farrago-0.9.0/initsql/createScottSchema.sql0000444000175000017500000000403111173714170022560 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/createScottSchema.sql#3 $ -- This script creates the SCOTT schema used by some of the unit tests. !set verbose true -- create local SCOTT schema create schema SCOTT; set schema 'SCOTT'; CREATE TABLE DEPT ( DEPTNO INTEGER NOT NULL PRIMARY KEY, DNAME VARCHAR(14), LOC VARCHAR(13)); INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK'), (20, 'RESEARCH', 'DALLAS'), (30, 'SALES', 'CHICAGO'), (40, 'OPERATIONS', 'BOSTON'); CREATE TABLE EMP ( EMPNO INTEGER NOT NULL PRIMARY KEY, ENAME VARCHAR(10), JOB VARCHAR(9), MGR INTEGER, HIREDATE DATE, SAL INTEGER, COMM INTEGER, DEPTNO INTEGER); INSERT INTO EMP VALUES (7369, 'SMITH', 'CLERK', 7902, DATE '1980-12-17', 800, NULL, 20), (7499, 'ALLEN', 'SALESMAN', 7698, DATE '1981-2-20', 1600, 300, 30), (7521, 'WARD', 'SALESMAN', 7698, DATE '1981-2-22', 1250, 500, 30), (7566, 'JONES', 'MANAGER', 7839, DATE '1981-4-2', 2975, NULL, 20), (7654, 'MARTIN', 'SALESMAN', 7698, DATE '1981-9-28', 1250, 1400, 30), (7698, 'BLAKE', 'MANAGER', 7839, DATE '1981-5-1', 2850, NULL, 30), (7782, 'CLARK', 'MANAGER', 7839, DATE '1981-6-9', 2450, NULL, 10), (7788, 'SCOTT', 'ANALYST', 7566, DATE '1987-7-13', 3000, NULL, 20), (7839, 'KING', 'PRESIDENT', NULL, DATE '1981-11-17', 5000, NULL, 10), (7844, 'TURNER', 'SALESMAN', 7698, DATE '1981-9-8', 1500, 0, 30), (7876, 'ADAMS', 'CLERK', 7788, DATE '1987-7-13', 1100, NULL, 20), (7900, 'JAMES', 'CLERK', 7698, DATE '1981-12-3', 950, NULL, 30), (7902, 'FORD', 'ANALYST', 7566, DATE '1981-12-3', 3000, NULL, 20), (7934, 'MILLER', 'CLERK', 7782, DATE '1982-1-23', 1300, NULL, 10); CREATE TABLE BONUS( ENAME VARCHAR(10) PRIMARY KEY, JOB VARCHAR(9), SAL INTEGER, COMM INTEGER); CREATE TABLE SALGRADE ( GRADE INTEGER PRIMARY KEY, LOSAL INTEGER, HISAL INTEGER); INSERT INTO SALGRADE VALUES (1, 700, 1200), (2, 1201, 1400), (3, 1401, 2000), (4, 2001, 3000), (5, 3001, 9999); -- End createScottSchema.sql eigenbase-farrago-0.9.0/initsql/testCleanup.ref0000444000175000017500000000071411173714170021427 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/testCleanup.ref#7 $ > -- This script effects a cleanup after unit tests > -- (actual cleanup work is done by FarragoTestCase.CleanUp), > -- and also verifies repository integrity. > !set verbose true > > -- should return empty set > select * from table(sys_boot.mgmt.repository_integrity_violations()); +--------------+---------+ | DESCRIPTION | MOF_ID | +--------------+---------+ +--------------+---------+ > > !quit eigenbase-farrago-0.9.0/initsql/createStorageWrappers.sql0000444000175000017500000000560311173714170023501 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/createStorageWrappers.sql#18 $ -- This script creates the builtin storage data wrappers !set verbose true -- create system-owned schema to hold objects like model extension plugin jars create or replace schema sys_boot.sys_boot; set schema 'sys_boot.sys_boot'; set path 'sys_boot.sys_boot'; -- add system objects not yet created create or replace procedure update_system_objects() language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoUpdateCatalogUDR.updateSystemObjects'; call update_system_objects(); -- update dangling system parameters create or replace procedure update_configuration() language java parameter style system defined java no sql external name 'class net.sf.farrago.syslib.FarragoUpdateCatalogUDR.updateConfiguration'; call update_configuration(); -- create wrapper for access to MDR repositories create or replace foreign data wrapper sys_mdr library 'class net.sf.farrago.namespace.mdr.MedMdrForeignDataWrapper' language java; -- create access to system's own MOF repository create or replace server sys_mof foreign data wrapper sys_mdr options(root_package_name 'MOF', schema_name 'MODEL'); -- creation of SYS_FEM and SYS_CWM delayed. -- See ./templates/createReposStorageServers.sql.* -- create wrapper for access to local FTRS data create or replace local data wrapper sys_ftrs library 'class net.sf.farrago.namespace.ftrs.FtrsDataWrapper' language java; -- create wrapper for access to local LucidDB column-store data create or replace local data wrapper sys_column_store library 'class com.lucidera.lcs.LcsDataWrapper' language java; -- create wrapper for access to local mock data create or replace local data wrapper sys_mock library 'class net.sf.farrago.namespace.mock.MedMockLocalDataWrapper' language java; -- create wrapper for access to foreign mock data create or replace foreign data wrapper sys_mock_foreign library 'class net.sf.farrago.namespace.mock.MedMockForeignDataWrapper' language java; -- create singleton server for local FTRS row-store data create or replace server sys_ftrs_data_server local data wrapper sys_ftrs; -- create singleton server for local LucidDB column-store data create or replace server sys_column_store_data_server local data wrapper sys_column_store; -- create singleton server for local mock row-store data create or replace server sys_mock_data_server local data wrapper sys_mock; -- create singleton server for foreign mock data create or replace server sys_mock_foreign_data_server foreign data wrapper sys_mock_foreign; -- create wrapper for access to JDBC data create or replace foreign data wrapper sys_jdbc library '${FARRAGO_HOME}/plugin/FarragoMedJdbc.jar' language java; -- create wrapper for access to flatfile data create or replace foreign data wrapper sys_file_wrapper library 'class net.sf.farrago.namespace.flatfile.FlatFileDataWrapper' language java; eigenbase-farrago-0.9.0/initsql/createJdbcViews.sql0000444000175000017500000004610711173714170022235 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/createJdbcViews.sql#24 $ -- This script creates a view schema used by JDBC metadata calls !set verbose true -- create views in system-owned schema sys_boot.jdbc_metadata create or replace schema sys_boot.jdbc_metadata; set schema 'sys_boot.jdbc_metadata'; set path 'sys_boot.jdbc_metadata'; create or replace function null_identifier() returns varchar(128) contains sql deterministic return cast(null as varchar(128)); create or replace function null_remarks() returns varchar(1024) contains sql deterministic return cast(null as varchar(1024)); create or replace function convert_cwm_nullable_to_int( cwm_nullability varchar(20)) returns integer contains sql deterministic return case when cwm_nullability='columnNoNulls' then 0 when cwm_nullability='columnNullable' then 1 else 2 end; create or replace function convert_cwm_nullable_to_string( cwm_nullability varchar(20)) returns varchar(3) contains sql deterministic return case when cwm_nullability='columnNoNulls' then 'NO' when cwm_nullability='columnNullable' then 'YES' else '' end; create or replace function convert_cwm_param_kind_to_int( cwm_param_kind varchar(10)) returns smallint contains sql deterministic return case when cwm_param_kind='pdk_in' then 1 when cwm_param_kind='pdk_inout' then 2 when cwm_param_kind='pdk_out' then 4 when cwm_param_kind='pdk_return' then 5 else 0 end; create or replace function convert_cwm_typename_to_literal_prefix( typename varchar(128)) returns varchar(128) contains sql deterministic return case when typename='VARCHAR' then trim('''') when typename='CHAR' then '''' when typename='VARBINARY' then 'X''' when typename='BINARY' then 'X''' when typename='DATE' then 'DATE ''' when typename='TIME' then 'TIME ''' when typename='TIMESTAMP' then 'TIMESTAMP ''' else cast(null as varchar(128)) end; create or replace function convert_cwm_typename_to_literal_suffix( typename varchar(128)) returns varchar(128) contains sql deterministic return case when typename='VARCHAR' then trim('''') when typename='CHAR' then '''' when typename='VARBINARY' then '''' when typename='BINARY' then '''' when typename='DATE' then '''' when typename='TIME' then '''' when typename='TIMESTAMP' then '''' else cast(null as varchar(128)) end; -- NOTE: currently unused return codes are 0 for statistic, 2 for hashed create or replace function convert_cwm_index_attributes_to_type( is_clustered boolean) returns smallint contains sql deterministic return case when is_clustered then 1 else 3 end; create or replace function convert_cwm_statistic_to_int(val numeric) returns int contains sql deterministic return case when val is null then 0 else cast (val as int) end; -- NOTE: don't include ORDER BY in the view definitions create or replace view schemas_view_internal as select c."name" as object_catalog, s."name" as object_schema, s."mofId" from sys_cwm."Relational"."Catalog" c inner join sys_cwm."Relational"."Schema" s on c."mofId" = s."namespace" ; create or replace view tables_view_internal as select s.object_catalog as table_cat, s.object_schema as table_schem, t."name" as table_name, null_remarks() as remarks, null_identifier() as type_cat, null_identifier() as type_schem, null_identifier() as type_name, null_identifier() as self_referencing_col_name, null_identifier() as ref_generation, t."mofId", t."mofClassName" from schemas_view_internal s inner join sys_cwm."Relational"."NamedColumnSet" t on s."mofId" = t."namespace" ; create or replace view catalogs_view as select c."name" as table_cat from sys_cwm."Relational"."Catalog" c ; grant select on catalogs_view to public; create or replace view schemas_view as select object_schema as table_schem, object_catalog as table_catalog from schemas_view_internal ; grant select on schemas_view to public; -- TODO: add 'GLOBAL TEMPORARY' and 'SYSTEM TABLE' create or replace view table_types_view_internal(table_type,uml_class_name) as values (trim('FOREIGN TABLE'),trim('ForeignTable')), ('TABLE','LocalTable'), ('VIEW','LocalView') ; create or replace view tables_view as select table_cat, table_schem, table_name, tt.table_type, remarks, type_cat, type_schem, type_name, self_referencing_col_name, ref_generation from tables_view_internal t, table_types_view_internal tt where t."mofClassName"=tt.uml_class_name ; grant select on tables_view to public; create or replace view table_types_view as select distinct table_type from table_types_view_internal ; grant select on table_types_view to public; -- TODO: get column_def by left-outer-join to get default value -- TODO: get source_data_type for distinct types -- TODO: get predefined numericPrecision and numericPrecisionRadix -- REVIEW: length/precision/scale/radix -- also all of above for attributes and procedure_columns create or replace view columns_view_internal as select t.table_cat, t.table_schem, t.table_name, c."name" as column_name, c."type", coalesce(c."length",c."precision") as column_size, 0 as buffer_len, c."scale" as dec_digits, convert_cwm_nullable_to_int(c."isNullable") as nullable, c."length" as char_octet_length, c."ordinal" + 1 as ordinal_position, convert_cwm_nullable_to_string(c."isNullable") as is_nullable, c."description" as remarks, c."mofId", c."lineageId" from tables_view_internal t inner join sys_fem."SQL2003"."AbstractColumn" c on t."mofId" = c."owner"; create or replace view columns_view as select c.table_cat, c.table_schem, c.table_name, c.column_name, t."typeNumber" as data_type, t."name" as type_name, c.column_size, c.buffer_len, c.dec_digits, cast(null as integer) as num_prec_radix, c.nullable, null_remarks() as remarks, null_remarks() as column_def, 0 as sql_data_type, 0 as sql_datetime_sub, c.char_octet_length, c.ordinal_position, c.is_nullable, null_identifier() as scope_catalog, null_identifier() as scope_schema, null_identifier() as scope_table, null_identifier() as source_data_type from columns_view_internal c inner join sys_cwm."Relational"."SQLDataType" t on c."type" = t."mofId"; grant select on columns_view to public; create or replace view udts_view_internal as select s.object_catalog as type_cat, s.object_schema as type_schem, u."name" as type_name, u."typeNumber" as data_type, u."mofId" from schemas_view_internal s inner join sys_fem."SQL2003"."UserDefinedType" u on s."mofId" = u."namespace" ; -- TODO: base_type for distinct types create or replace view udts_view as select u.type_cat, u.type_schem, u.type_name, null_identifier() as class_name, u.data_type, null_remarks() as remarks, cast (null as smallint) as base_type from udts_view_internal u ; grant select on udts_view to public; create or replace view attributes_view_internal as select u.type_cat, u.type_schem, u.type_name, a."name" as attr_name, coalesce(a."length",a."precision") as attr_size, a."scale" as decimal_digits, convert_cwm_nullable_to_int(a."isNullable") as nullable, a."length" as char_octet_length, a."ordinal" + 1 as ordinal_position, convert_cwm_nullable_to_string(a."isNullable") as is_nullable, a."type", a."mofId" from udts_view_internal u inner join sys_fem."SQL2003"."SQLTypeAttribute" a on u."mofId" = a."owner" ; create or replace view attributes_view as select a.type_cat, a.type_schem, a.type_name, a.attr_name, t."typeNumber" as data_type, t."name" as attr_type_name, a.attr_size, a.decimal_digits, cast(null as integer) as num_prec_radix, a.nullable, null_remarks() as remarks, null_remarks() as attr_def, 0 as sql_data_type, 0 as sql_datetime_sub, a.char_octet_length, a.ordinal_position, a.is_nullable, null_identifier() as scope_catalog, null_identifier() as scope_schema, null_identifier() as scope_table, null_identifier() as source_data_type from attributes_view_internal a inner join sys_cwm."Relational"."SQLDataType" t on a."type" = t."mofId" ; grant select on attributes_view to public; -- TODO: find out why replacing BehavioralFeature below with Method or -- Routine doesn't work (causes assignment of null to NOT NULL). Must be -- a bug in Farrago's MDR namespace support. create or replace view procedures_view_internal as select s.object_catalog as procedure_cat, s.object_schema as procedure_schem, r."name" as procedure_name, r."mofId" from schemas_view_internal s inner join sys_cwm."Behavioral"."BehavioralFeature" r on s."mofId" = r."namespace" ; -- TODO: other values for procedure_type once we support procedures -- that return result sets create or replace view procedures_view as select p.procedure_cat, p.procedure_schem, p.procedure_name, null_identifier() as reserved1, null_identifier() as reserved2, null_identifier() as reserved3, null_remarks() as remarks, cast(1 as smallint) as procedure_type from procedures_view_internal p ; grant select on procedures_view to public; create or replace view procedure_columns_view_internal as select p.procedure_cat, p.procedure_schem, p.procedure_name, rp."name" as column_name, convert_cwm_param_kind_to_int(rp."kind") as column_type, rp."precision" as "PRECISION", rp."length" as length, rp."scale" as scale, case when rp."kind"='pdk_return' then 0 else rp."ordinal" + 1 end as column_ordinal, rp."type", rp."mofId" from procedures_view_internal p inner join sys_fem."SQL2003"."RoutineParameter" rp on p."mofId" = rp."behavioralFeature" ; create or replace view procedure_columns_view as select pc.procedure_cat, pc.procedure_schem, pc.procedure_name, pc.column_name, pc.column_type, t."typeNumber" as data_type, t."name" as type_name, pc."PRECISION", pc.length, pc.scale, cast(null as integer) as radix, cast(1 as smallint) as nullable, null_remarks() as remarks, pc.column_ordinal from procedure_columns_view_internal pc inner join sys_cwm."Relational"."SQLDataType" t on pc."type" = t."mofId" ; grant select on procedure_columns_view to public; -- TODO: refine precision, case_sensitive, searchable, minimum/maximum_scale -- as we add LOB, NUMERIC, and UNICODE data types; unsigned should -- be null for non-numerics; case_sensitive should be null for -- non-character; support create_params create or replace view type_info_view as select t."name" as type_name, t."typeNumber" as data_type, coalesce( t."numericPrecision", t."characterMaximumLength", t."dateTimePrecision") as "PRECISION", convert_cwm_typename_to_literal_prefix(t."name") as literal_prefix, convert_cwm_typename_to_literal_suffix(t."name") as literal_suffix, null_identifier() as create_params, cast(1 as smallint) as nullable, true as case_sensitive, 3 as searchable, false as unsigned_attribute, false as fixed_prec_scale, false as auto_increment, null_identifier() as local_type_name, cast(null as smallint) as minimum_scale, cast(null as smallint) as maximum_scale, cast(null as integer) as sql_data_type, cast(null as integer) as sql_datetime_sub, "numericPrecisionRadix" as num_prec_radix from sys_cwm."Relational"."SQLSimpleType" t ; grant select on type_info_view to public; create or replace view primary_keys_view_internal as select t.table_cat, t.table_schem, t.table_name, k."name" as pk_name, k."mofId" from tables_view_internal t inner join sys_fem."SQL2003"."PrimaryKeyConstraint" k on t."mofId" = k."namespace" ; create or replace view primary_keys_view as select k.table_cat, k.table_schem, k.table_name, c."name" as column_name, c."ordinal" + 1 as key_seq, k.pk_name from primary_keys_view_internal k inner join sys_fem."SQL2003"."KeyComponent" c on k."mofId" = c."KeyConstraint" ; grant select on primary_keys_view to public; -- TODO: use an outer join with histograms for index cardinality -- or store that statistic in the catalog create or replace view index_info_internal as select t.table_cat, t.table_schem, t.table_name, (not i."isUnique") as non_unique, t.table_cat as index_qualifier, i."name" as index_name, convert_cwm_index_attributes_to_type(i."isClustered") as type, 0 as "CARDINALITY", i."pageCount" as pages, cast(null as varchar(128)) as filter_condition, i."mofId" from tables_view_internal t inner join sys_fem."MED"."LocalIndex" i on t."mofId" = i."spannedClass" ; create or replace view table_row_counts_internal as select t.table_cat, t.table_schem, t.table_name, acs."rowCount" as "CARDINALITY", t."mofId" from tables_view_internal t inner join sys_fem.sql2003."AbstractColumnSet" acs on t."mofId" = acs."mofId" ; -- NOTE: would be cleaner to have a separate view for page counts -- but MedMdr joins work best when joining simple tables create or replace view table_stats_internal as select t.table_cat, t.table_schem, t.table_name, t."CARDINALITY", sum(i."pageCount") as pages, t."mofId" from table_row_counts_internal t inner join sys_fem.med."LocalIndex" i on t."mofId" = i."spannedClass" group by t."mofId", t.table_cat, t.table_schem, t.table_name, t."CARDINALITY" ; -- left outer join needed to handle cases where indexes are not associated -- with any specific column create or replace view index_info_view as select i.table_cat, i.table_schem, i.table_name, i.non_unique, i.table_cat as index_qualifier, i.index_name, i.type, c."ordinal" + 1 as ordinal_position, c."name" as column_name, 'A' as asc_or_desc, i."CARDINALITY", convert_cwm_statistic_to_int(i.pages) as pages, i.filter_condition from index_info_internal i left outer join sys_fem."MED"."LocalIndexColumn" c on i."mofId" = c."index" union select t.table_cat, t.table_schem, t.table_name, false as non_unique, null_identifier() as index_qualifier, null_identifier() as index_name, 0 as type, 0 as ordinal_position, null_identifier() as column_name, cast(null as varchar(128)) as asc_or_desc, convert_cwm_statistic_to_int(t."CARDINALITY") as "CARDINALITY", convert_cwm_statistic_to_int(t.pages) as pages, cast(null as varchar(128)) as filter_condition from table_stats_internal t ; grant select on index_info_view to public; create or replace view empty_view as select * from (values(0)) where false; create or replace view super_tables_view as select null_identifier() as table_cat, null_identifier() as table_schem, null_identifier() as table_name, null_identifier() as supertable_name from empty_view; grant select on super_tables_view to public; create or replace view super_types_view as select null_identifier() as type_cat, null_identifier() as type_schem, null_identifier() as type_name, null_identifier() as supertype_cat, null_identifier() as supertype_schem, null_identifier() as supertype_name from empty_view; grant select on super_types_view to public; create or replace view exported_keys_view as select null_identifier() as pktable_cat, null_identifier() as pktable_schem, null_identifier() as pktable_name, null_identifier() as pkcolumn_name, null_identifier() as fktable_cat, null_identifier() as fktable_schem, null_identifier() as fktable_name, null_identifier() as fkcolumn_name, cast(null as smallint) as key_seq, cast(null as smallint) as update_rule, cast(null as smallint) as delete_rule, null_identifier() as fk_name, null_identifier() as pk_name, cast(null as smallint) as deferrability from empty_view; grant select on exported_keys_view to public; create or replace view imported_keys_view as select null_identifier() as pktable_cat, null_identifier() as pktable_schem, null_identifier() as pktable_name, null_identifier() as pkcolumn_name, null_identifier() as fktable_cat, null_identifier() as fktable_schem, null_identifier() as fktable_name, null_identifier() as fkcolumn_name, cast(null as smallint) as key_seq, cast(null as smallint) as update_rule, cast(null as smallint) as delete_rule, null_identifier() as fk_name, null_identifier() as pk_name, cast(null as smallint) as deferrability from empty_view; grant select on imported_keys_view to public; create or replace view cross_reference_view as select null_identifier() as pktable_cat, null_identifier() as pktable_schem, null_identifier() as pktable_name, null_identifier() as pkcolumn_name, null_identifier() as fktable_cat, null_identifier() as fktable_schem, null_identifier() as fktable_name, null_identifier() as fkcolumn_name, cast(null as smallint) as key_seq, cast(null as smallint) as update_rule, cast(null as smallint) as delete_rule, null_identifier() as fk_name, null_identifier() as pk_name, cast(null as smallint) as deferrability from empty_view; grant select on cross_reference_view to public; -- TODO: all the rest -- just a placeholder for now create or replace schema localdb.information_schema; eigenbase-farrago-0.9.0/initsql/templates/0000755000175000017500000000000011173714170020440 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/initsql/templates/createReposStorageServers.sql.hibernate.tmpl0000444000175000017500000000204011173714170031241 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/templates/createReposStorageServers.sql.hibernate.tmpl#1 $ -- This script creates the builtin storage data servers for repository object -- access when Enki/Hibernate is used for repository storage. !set verbose true set schema 'sys_boot.sys_boot'; set path 'sys_boot.sys_boot'; -- create access to system's own CWM repository create or replace server sys_cwm foreign data wrapper sys_jdbc options( jndi_name 'java:ENKI_DATASOURCE', schema_name 'DUMMY', table_prefix_mapping '%.FEM_VT_Behavioral_%:Behavioral.%;%.FEM_VT_Core_%:Core.%;%.FEM_VT_DataTypes_%:DataTypes.%;%.FEM_VT_Instance_%:Instance.%;%.FEM_VT_KeysIndexes_%:KeysIndexes.%;%.FEM_VT_Relational_%:Relational.%'); -- create access to system's own Farrago-specific portion of repository create or replace server sys_fem foreign data wrapper sys_jdbc options( jndi_name 'java:ENKI_DATASOURCE', schema_name 'DUMMY', table_prefix_mapping '%.FEM_VT_Config_%:Config.%;%.FEM_VT_Med_%:MED.%;%.FEM_VT_Security_%:Security.%;%.FEM_VT_Sql2003_%:SQL2003.%'); eigenbase-farrago-0.9.0/initsql/templates/createReposStorageServers.ref.default.tmpl0000444000175000017500000000124111173714170030703 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/templates/createReposStorageServers.ref.default.tmpl#1 $ > -- This script creates the builtin storage data servers for repository object > -- access when Netbeans MDR is used for repository storage. > > !set verbose true > > set schema 'sys_boot.sys_boot'; > set path 'sys_boot.sys_boot'; > > -- create access to system's own CWM repository > create or replace server sys_cwm > foreign data wrapper sys_mdr > options(root_package_name 'CWM'); > > -- create access to system's own Farrago-specific portion of repository > create or replace server sys_fem > foreign data wrapper sys_mdr > options(root_package_name 'FEM'); > > !quit eigenbase-farrago-0.9.0/initsql/templates/createReposStorageServers.sql.default.tmpl0000444000175000017500000000116211173714170030730 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/templates/createReposStorageServers.sql.default.tmpl#1 $ -- This script creates the builtin storage data servers for repository object -- access when Netbeans MDR is used for repository storage. !set verbose true set schema 'sys_boot.sys_boot'; set path 'sys_boot.sys_boot'; -- create access to system's own CWM repository create or replace server sys_cwm foreign data wrapper sys_mdr options(root_package_name 'CWM'); -- create access to system's own Farrago-specific portion of repository create or replace server sys_fem foreign data wrapper sys_mdr options(root_package_name 'FEM'); eigenbase-farrago-0.9.0/initsql/templates/createReposStorageServers.ref.hibernate.tmpl0000444000175000017500000000213311173714170031221 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/templates/createReposStorageServers.ref.hibernate.tmpl#1 $ > -- This script creates the builtin storage data servers for repository object > -- access when Enki/Hibernate is used for repository storage. > > !set verbose true > > set schema 'sys_boot.sys_boot'; > set path 'sys_boot.sys_boot'; > > -- create access to system's own CWM repository > create or replace server sys_cwm > foreign data wrapper sys_jdbc > options( > jndi_name 'java:ENKI_DATASOURCE', > schema_name 'DUMMY', > table_prefix_mapping '%.FEM_VT_Behavioral_%:Behavioral.%;%.FEM_VT_Core_%:Core.%;%.FEM_VT_DataTypes_%:DataTypes.%;%.FEM_VT_Instance_%:Instance.%;%.FEM_VT_KeysIndexes_%:KeysIndexes.%;%.FEM_VT_Relational_%:Relational.%'); > > -- create access to system's own Farrago-specific portion of repository > create or replace server sys_fem > foreign data wrapper sys_jdbc > options( > jndi_name 'java:ENKI_DATASOURCE', > schema_name 'DUMMY', > table_prefix_mapping '%.FEM_VT_Config_%:Config.%;%.FEM_VT_Med_%:MED.%;%.FEM_VT_Security_%:Security.%;%.FEM_VT_Sql2003_%:SQL2003.%'); > > !quit eigenbase-farrago-0.9.0/initsql/createJdbcViews.ref0000444000175000017500000005065011173714170022210 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/createJdbcViews.ref#28 $ > -- This script creates a view schema used by JDBC metadata calls > > !set verbose true > > -- create views in system-owned schema sys_boot.jdbc_metadata > create or replace schema sys_boot.jdbc_metadata; > set schema 'sys_boot.jdbc_metadata'; > set path 'sys_boot.jdbc_metadata'; > > create or replace function null_identifier() > returns varchar(128) > contains sql > deterministic > return cast(null as varchar(128)); > > create or replace function null_remarks() > returns varchar(1024) > contains sql > deterministic > return cast(null as varchar(1024)); > > create or replace function convert_cwm_nullable_to_int( > cwm_nullability varchar(20)) > returns integer > contains sql > deterministic > return case > when cwm_nullability='columnNoNulls' then 0 > when cwm_nullability='columnNullable' then 1 > else 2 > end; > > create or replace function convert_cwm_nullable_to_string( > cwm_nullability varchar(20)) > returns varchar(3) > contains sql > deterministic > return case > when cwm_nullability='columnNoNulls' then 'NO' > when cwm_nullability='columnNullable' then 'YES' > else '' > end; > > create or replace function convert_cwm_param_kind_to_int( > cwm_param_kind varchar(10)) > returns smallint > contains sql > deterministic > return case > when cwm_param_kind='pdk_in' then 1 > when cwm_param_kind='pdk_inout' then 2 > when cwm_param_kind='pdk_out' then 4 > when cwm_param_kind='pdk_return' then 5 > else 0 > end; > > create or replace function convert_cwm_typename_to_literal_prefix( > typename varchar(128)) > returns varchar(128) > contains sql > deterministic > return case > when typename='VARCHAR' then trim('''') > when typename='CHAR' then '''' > when typename='VARBINARY' then 'X''' > when typename='BINARY' then 'X''' > when typename='DATE' then 'DATE ''' > when typename='TIME' then 'TIME ''' > when typename='TIMESTAMP' then 'TIMESTAMP ''' > else cast(null as varchar(128)) > end; > > create or replace function convert_cwm_typename_to_literal_suffix( > typename varchar(128)) > returns varchar(128) > contains sql > deterministic > return case > when typename='VARCHAR' then trim('''') > when typename='CHAR' then '''' > when typename='VARBINARY' then '''' > when typename='BINARY' then '''' > when typename='DATE' then '''' > when typename='TIME' then '''' > when typename='TIMESTAMP' then '''' > else cast(null as varchar(128)) > end; > > -- NOTE: currently unused return codes are 0 for statistic, 2 for hashed > create or replace function convert_cwm_index_attributes_to_type( > is_clustered boolean) > returns smallint > contains sql > deterministic > return case > when is_clustered then 1 > else 3 > end; > > create or replace function convert_cwm_statistic_to_int(val numeric) > returns int > contains sql > deterministic > return case > when val is null then 0 > else cast (val as int) > end; > > -- NOTE: don't include ORDER BY in the view definitions > > create or replace view schemas_view_internal as > select > c."name" as object_catalog, > s."name" as object_schema, > s."mofId" > from > sys_cwm."Relational"."Catalog" c > inner join > sys_cwm."Relational"."Schema" s > on > c."mofId" = s."namespace" > ; > > create or replace view tables_view_internal as > select > s.object_catalog as table_cat, > s.object_schema as table_schem, > t."name" as table_name, > null_remarks() as remarks, > null_identifier() as type_cat, > null_identifier() as type_schem, > null_identifier() as type_name, > null_identifier() as self_referencing_col_name, > null_identifier() as ref_generation, > t."mofId", > t."mofClassName" > from > schemas_view_internal s > inner join > sys_cwm."Relational"."NamedColumnSet" t > on > s."mofId" = t."namespace" > ; > > create or replace view catalogs_view as > select > c."name" as table_cat > from > sys_cwm."Relational"."Catalog" c > ; > grant select on catalogs_view to public; > > create or replace view schemas_view as > select > object_schema as table_schem, > object_catalog as table_catalog > from > schemas_view_internal > ; > grant select on schemas_view to public; > > -- TODO: add 'GLOBAL TEMPORARY' and 'SYSTEM TABLE' > create or replace view table_types_view_internal(table_type,uml_class_name) as > values > (trim('FOREIGN TABLE'),trim('ForeignTable')), > ('TABLE','LocalTable'), > ('VIEW','LocalView') > ; > > create or replace view tables_view as > select > table_cat, > table_schem, > table_name, > tt.table_type, > remarks, > type_cat, > type_schem, > type_name, > self_referencing_col_name, > ref_generation > from > tables_view_internal t, > table_types_view_internal tt > where > t."mofClassName"=tt.uml_class_name > ; > grant select on tables_view to public; > > create or replace view table_types_view as > select distinct > table_type > from > table_types_view_internal > ; > grant select on table_types_view to public; > > -- TODO: get column_def by left-outer-join to get default value > -- TODO: get source_data_type for distinct types > -- TODO: get predefined numericPrecision and numericPrecisionRadix > -- REVIEW: length/precision/scale/radix > -- also all of above for attributes and procedure_columns > > create or replace view columns_view_internal as > select > t.table_cat, > t.table_schem, > t.table_name, > c."name" as column_name, > c."type", > coalesce(c."length",c."precision") as column_size, > 0 as buffer_len, > c."scale" as dec_digits, > convert_cwm_nullable_to_int(c."isNullable") as nullable, > c."length" as char_octet_length, > c."ordinal" + 1 as ordinal_position, > convert_cwm_nullable_to_string(c."isNullable") as is_nullable, > c."description" as remarks, > c."mofId", > c."lineageId" > from > tables_view_internal t > inner join > sys_fem."SQL2003"."AbstractColumn" c > on > t."mofId" = c."owner"; > > create or replace view columns_view as > select > c.table_cat, > c.table_schem, > c.table_name, > c.column_name, > t."typeNumber" as data_type, > t."name" as type_name, > c.column_size, > c.buffer_len, > c.dec_digits, > cast(null as integer) as num_prec_radix, > c.nullable, > null_remarks() as remarks, > null_remarks() as column_def, > 0 as sql_data_type, > 0 as sql_datetime_sub, > c.char_octet_length, > c.ordinal_position, > c.is_nullable, > null_identifier() as scope_catalog, > null_identifier() as scope_schema, > null_identifier() as scope_table, > null_identifier() as source_data_type > from > columns_view_internal c > inner join > sys_cwm."Relational"."SQLDataType" t > on > c."type" = t."mofId"; > grant select on columns_view to public; > > create or replace view udts_view_internal as > select > s.object_catalog as type_cat, > s.object_schema as type_schem, > u."name" as type_name, > u."typeNumber" as data_type, > u."mofId" > from > schemas_view_internal s > inner join > sys_fem."SQL2003"."UserDefinedType" u > on > s."mofId" = u."namespace" > ; > > -- TODO: base_type for distinct types > > create or replace view udts_view as > select > u.type_cat, > u.type_schem, > u.type_name, > null_identifier() as class_name, > u.data_type, > null_remarks() as remarks, > cast (null as smallint) as base_type > from > udts_view_internal u > ; > grant select on udts_view to public; > > create or replace view attributes_view_internal as > select > u.type_cat, > u.type_schem, > u.type_name, > a."name" as attr_name, > coalesce(a."length",a."precision") as attr_size, > a."scale" as decimal_digits, > convert_cwm_nullable_to_int(a."isNullable") as nullable, > a."length" as char_octet_length, > a."ordinal" + 1 as ordinal_position, > convert_cwm_nullable_to_string(a."isNullable") as is_nullable, > a."type", > a."mofId" > from > udts_view_internal u > inner join > sys_fem."SQL2003"."SQLTypeAttribute" a > on > u."mofId" = a."owner" > ; > > create or replace view attributes_view as > select > a.type_cat, > a.type_schem, > a.type_name, > a.attr_name, > t."typeNumber" as data_type, > t."name" as attr_type_name, > a.attr_size, > a.decimal_digits, > cast(null as integer) as num_prec_radix, > a.nullable, > null_remarks() as remarks, > null_remarks() as attr_def, > 0 as sql_data_type, > 0 as sql_datetime_sub, > a.char_octet_length, > a.ordinal_position, > a.is_nullable, > null_identifier() as scope_catalog, > null_identifier() as scope_schema, > null_identifier() as scope_table, > null_identifier() as source_data_type > from > attributes_view_internal a > inner join > sys_cwm."Relational"."SQLDataType" t > on > a."type" = t."mofId" > ; > grant select on attributes_view to public; > > -- TODO: find out why replacing BehavioralFeature below with Method or > -- Routine doesn't work (causes assignment of null to NOT NULL). Must be > -- a bug in Farrago's MDR namespace support. > > create or replace view procedures_view_internal as > select > s.object_catalog as procedure_cat, > s.object_schema as procedure_schem, > r."name" as procedure_name, > r."mofId" > from > schemas_view_internal s > inner join > sys_cwm."Behavioral"."BehavioralFeature" r > on > s."mofId" = r."namespace" > ; > > -- TODO: other values for procedure_type once we support procedures > -- that return result sets > > create or replace view procedures_view as > select > p.procedure_cat, > p.procedure_schem, > p.procedure_name, > null_identifier() as reserved1, > null_identifier() as reserved2, > null_identifier() as reserved3, > null_remarks() as remarks, > cast(1 as smallint) as procedure_type > from > procedures_view_internal p > ; > grant select on procedures_view to public; > > create or replace view procedure_columns_view_internal as > select > p.procedure_cat, > p.procedure_schem, > p.procedure_name, > rp."name" as column_name, > convert_cwm_param_kind_to_int(rp."kind") as column_type, > rp."precision" as "PRECISION", > rp."length" as length, > rp."scale" as scale, > case when rp."kind"='pdk_return' then 0 > else rp."ordinal" + 1 end as column_ordinal, > rp."type", > rp."mofId" > from > procedures_view_internal p > inner join > sys_fem."SQL2003"."RoutineParameter" rp > on > p."mofId" = rp."behavioralFeature" > ; > > create or replace view procedure_columns_view as > select > pc.procedure_cat, > pc.procedure_schem, > pc.procedure_name, > pc.column_name, > pc.column_type, > t."typeNumber" as data_type, > t."name" as type_name, > pc."PRECISION", > pc.length, > pc.scale, > cast(null as integer) as radix, > cast(1 as smallint) as nullable, > null_remarks() as remarks, > pc.column_ordinal > from > procedure_columns_view_internal pc > inner join > sys_cwm."Relational"."SQLDataType" t > on > pc."type" = t."mofId" > ; > grant select on procedure_columns_view to public; > > -- TODO: refine precision, case_sensitive, searchable, minimum/maximum_scale > -- as we add LOB, NUMERIC, and UNICODE data types; unsigned should > -- be null for non-numerics; case_sensitive should be null for > -- non-character; support create_params > > create or replace view type_info_view as > select > t."name" as type_name, > t."typeNumber" as data_type, > coalesce( > t."numericPrecision", > t."characterMaximumLength", > t."dateTimePrecision") as "PRECISION", > convert_cwm_typename_to_literal_prefix(t."name") as literal_prefix, > convert_cwm_typename_to_literal_suffix(t."name") as literal_suffix, > null_identifier() as create_params, > cast(1 as smallint) as nullable, > true as case_sensitive, > 3 as searchable, > false as unsigned_attribute, > false as fixed_prec_scale, > false as auto_increment, > null_identifier() as local_type_name, > cast(null as smallint) as minimum_scale, > cast(null as smallint) as maximum_scale, > cast(null as integer) as sql_data_type, > cast(null as integer) as sql_datetime_sub, > "numericPrecisionRadix" as num_prec_radix > from > sys_cwm."Relational"."SQLSimpleType" t > ; > grant select on type_info_view to public; > > create or replace view primary_keys_view_internal as > select > t.table_cat, > t.table_schem, > t.table_name, > k."name" as pk_name, > k."mofId" > from > tables_view_internal t > inner join > sys_fem."SQL2003"."PrimaryKeyConstraint" k > on > t."mofId" = k."namespace" > ; > > create or replace view primary_keys_view as > select > k.table_cat, > k.table_schem, > k.table_name, > c."name" as column_name, > c."ordinal" + 1 as key_seq, > k.pk_name > from > primary_keys_view_internal k > inner join > sys_fem."SQL2003"."KeyComponent" c > on > k."mofId" = c."KeyConstraint" > ; > grant select on primary_keys_view to public; > > -- TODO: use an outer join with histograms for index cardinality > -- or store that statistic in the catalog > > create or replace view index_info_internal as > select > t.table_cat, > t.table_schem, > t.table_name, > (not i."isUnique") as non_unique, > t.table_cat as index_qualifier, > i."name" as index_name, > convert_cwm_index_attributes_to_type(i."isClustered") as type, > 0 as "CARDINALITY", > i."pageCount" as pages, > cast(null as varchar(128)) as filter_condition, > i."mofId" > from > tables_view_internal t > inner join > sys_fem."MED"."LocalIndex" i > on > t."mofId" = i."spannedClass" > ; > > create or replace view table_row_counts_internal as > select > t.table_cat, > t.table_schem, > t.table_name, > acs."rowCount" as "CARDINALITY", > t."mofId" > from > tables_view_internal t > inner join > sys_fem.sql2003."AbstractColumnSet" acs > on > t."mofId" = acs."mofId" > ; > > -- NOTE: would be cleaner to have a separate view for page counts > -- but MedMdr joins work best when joining simple tables > create or replace view table_stats_internal as > select > t.table_cat, > t.table_schem, > t.table_name, > t."CARDINALITY", > sum(i."pageCount") as pages, > t."mofId" > from > table_row_counts_internal t > inner join > sys_fem.med."LocalIndex" i > on > t."mofId" = i."spannedClass" > group by > t."mofId", > t.table_cat, > t.table_schem, > t.table_name, > t."CARDINALITY" > ; > > -- left outer join needed to handle cases where indexes are not associated > -- with any specific column > create or replace view index_info_view as > select > i.table_cat, > i.table_schem, > i.table_name, > i.non_unique, > i.table_cat as index_qualifier, > i.index_name, > i.type, > c."ordinal" + 1 as ordinal_position, > c."name" as column_name, > 'A' as asc_or_desc, > i."CARDINALITY", > convert_cwm_statistic_to_int(i.pages) as pages, > i.filter_condition > from > index_info_internal i > left outer join > sys_fem."MED"."LocalIndexColumn" c > on > i."mofId" = c."index" > union > select > t.table_cat, > t.table_schem, > t.table_name, > false as non_unique, > null_identifier() as index_qualifier, > null_identifier() as index_name, > 0 as type, > 0 as ordinal_position, > null_identifier() as column_name, > cast(null as varchar(128)) as asc_or_desc, > convert_cwm_statistic_to_int(t."CARDINALITY") as "CARDINALITY", > convert_cwm_statistic_to_int(t.pages) as pages, > cast(null as varchar(128)) as filter_condition > from > table_stats_internal t > ; > grant select on index_info_view to public; > > create or replace view empty_view as > select * from (values(0)) where false; > > create or replace view super_tables_view as > select > null_identifier() as table_cat, > null_identifier() as table_schem, > null_identifier() as table_name, > null_identifier() as supertable_name > from empty_view; > grant select on super_tables_view to public; > > create or replace view super_types_view as > select > null_identifier() as type_cat, > null_identifier() as type_schem, > null_identifier() as type_name, > null_identifier() as supertype_cat, > null_identifier() as supertype_schem, > null_identifier() as supertype_name > from empty_view; > grant select on super_types_view to public; > > create or replace view exported_keys_view as > select > null_identifier() as pktable_cat, > null_identifier() as pktable_schem, > null_identifier() as pktable_name, > null_identifier() as pkcolumn_name, > null_identifier() as fktable_cat, > null_identifier() as fktable_schem, > null_identifier() as fktable_name, > null_identifier() as fkcolumn_name, > cast(null as smallint) as key_seq, > cast(null as smallint) as update_rule, > cast(null as smallint) as delete_rule, > null_identifier() as fk_name, > null_identifier() as pk_name, > cast(null as smallint) as deferrability > from empty_view; > grant select on exported_keys_view to public; > > create or replace view imported_keys_view as > select > null_identifier() as pktable_cat, > null_identifier() as pktable_schem, > null_identifier() as pktable_name, > null_identifier() as pkcolumn_name, > null_identifier() as fktable_cat, > null_identifier() as fktable_schem, > null_identifier() as fktable_name, > null_identifier() as fkcolumn_name, > cast(null as smallint) as key_seq, > cast(null as smallint) as update_rule, > cast(null as smallint) as delete_rule, > null_identifier() as fk_name, > null_identifier() as pk_name, > cast(null as smallint) as deferrability > from empty_view; > grant select on imported_keys_view to public; > > create or replace view cross_reference_view as > select > null_identifier() as pktable_cat, > null_identifier() as pktable_schem, > null_identifier() as pktable_name, > null_identifier() as pkcolumn_name, > null_identifier() as fktable_cat, > null_identifier() as fktable_schem, > null_identifier() as fktable_name, > null_identifier() as fkcolumn_name, > cast(null as smallint) as key_seq, > cast(null as smallint) as update_rule, > cast(null as smallint) as delete_rule, > null_identifier() as fk_name, > null_identifier() as pk_name, > cast(null as smallint) as deferrability > from empty_view; > grant select on cross_reference_view to public; > > -- TODO: all the rest > > -- just a placeholder for now > create or replace schema localdb.information_schema; > > !quit eigenbase-farrago-0.9.0/initsql/createStorageWrappers.ref0000444000175000017500000000610611173714170023455 0ustar drazzibdrazzib> -- $Id: //open/dev/farrago/initsql/createStorageWrappers.ref#21 $ > -- This script creates the builtin storage data wrappers > > !set verbose true > > -- create system-owned schema to hold objects like model extension plugin jars > create or replace schema sys_boot.sys_boot; > > set schema 'sys_boot.sys_boot'; > set path 'sys_boot.sys_boot'; > > -- add system objects not yet created > create or replace procedure update_system_objects() > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoUpdateCatalogUDR.updateSystemObjects'; > > call update_system_objects(); > > -- update dangling system parameters > create or replace procedure update_configuration() > language java > parameter style system defined java > no sql > external name > 'class net.sf.farrago.syslib.FarragoUpdateCatalogUDR.updateConfiguration'; > > call update_configuration(); > > > -- create wrapper for access to MDR repositories > create or replace foreign data wrapper sys_mdr > library 'class net.sf.farrago.namespace.mdr.MedMdrForeignDataWrapper' > language java; > > > -- create access to system's own MOF repository > create or replace server sys_mof > foreign data wrapper sys_mdr > options(root_package_name 'MOF', schema_name 'MODEL'); > > -- creation of SYS_FEM and SYS_CWM delayed. > -- See ./templates/createReposStorageServers.sql.* > > > -- create wrapper for access to local FTRS data > create or replace local data wrapper sys_ftrs > library 'class net.sf.farrago.namespace.ftrs.FtrsDataWrapper' > language java; > > -- create wrapper for access to local LucidDB column-store data > create or replace local data wrapper sys_column_store > library 'class com.lucidera.lcs.LcsDataWrapper' > language java; > > -- create wrapper for access to local mock data > create or replace local data wrapper sys_mock > library 'class net.sf.farrago.namespace.mock.MedMockLocalDataWrapper' > language java; > > -- create wrapper for access to foreign mock data > create or replace foreign data wrapper sys_mock_foreign > library 'class net.sf.farrago.namespace.mock.MedMockForeignDataWrapper' > language java; > > -- create singleton server for local FTRS row-store data > create or replace server sys_ftrs_data_server > local data wrapper sys_ftrs; > > -- create singleton server for local LucidDB column-store data > create or replace server sys_column_store_data_server > local data wrapper sys_column_store; > > -- create singleton server for local mock row-store data > create or replace server sys_mock_data_server > local data wrapper sys_mock; > > -- create singleton server for foreign mock data > create or replace server sys_mock_foreign_data_server > foreign data wrapper sys_mock_foreign; > > -- create wrapper for access to JDBC data > create or replace foreign data wrapper sys_jdbc > library '${FARRAGO_HOME}/plugin/FarragoMedJdbc.jar' > language java; > > -- create wrapper for access to flatfile data > create or replace foreign data wrapper sys_file_wrapper > library 'class net.sf.farrago.namespace.flatfile.FlatFileDataWrapper' > language java; > > !quit eigenbase-farrago-0.9.0/initsql/testCleanup.sql0000444000175000017500000000050511173714170021450 0ustar drazzibdrazzib-- $Id: //open/dev/farrago/initsql/testCleanup.sql#3 $ -- This script effects a cleanup after unit tests -- (actual cleanup work is done by FarragoTestCase.CleanUp), -- and also verifies repository integrity. !set verbose true -- should return empty set select * from table(sys_boot.mgmt.repository_integrity_violations()); eigenbase-farrago-0.9.0/build.bat0000444000175000017500000000064411173714170016550 0ustar drazzibdrazzib@rem Farrago transactional SQL DBMS @rem $Id: //open/dev/farrago/build.bat#3 $ @rem Copyright (C) 2002-2009 Julian Hyde @set SRCROOT=%~dp0 @set HOME_DRIVE=E @set JAVACC_HOME=%HOME_DRIVE%:\javacc-3.2 @set ANT_HOME=%HOME_DRIVE%:\apache-ant-1.6.0 @set JUNIT_HOME=%HOME_DRIVE%:/junit3.8.1 @set CLASSPATH=%JAVACC_HOME%\bin\lib\JavaCC.zip;%SRCROOT%\classes @%ANT_HOME%\bin\ant %1 %2 %3 %4 %5 %6 %7 %8 %9 @rem End build.bat eigenbase-farrago-0.9.0/COPYING0000444000175000017500000004546611173714170016027 0ustar drazzibdrazzibThis software is released under the GNU General Public License, which is reproduced below. In addition, as a special exception, The Eigenbase Project gives permission to link the code of this program with the following GPL-incompatible libraries, and distribute linked combinations including all of these: - MDR library from Netbeans (or modified versions of MDR that use the same license as MDR--the Sun Public License), including JMI interfaces from Sun Microsystems - All standard Java runtime libraries distributed by Sun Microsystems as part of any release of J2SE or J2EE - MOF, UML, and CWM model definitions from Object Management Group - Apache Commons from the Apache Software Foundation - Hibernate and supporting libraries from Red Hat Middleware You must obey the GNU General Public License in all respects for all of the code used other than the libraries listed above. If you modify this program, you may extend this exception to your version of the program, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Any trademarks used above are property of their respective owners. ====================================================================== GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. eigenbase-farrago-0.9.0/farragoServer0000555000175000017500000000027411173714170017516 0ustar drazzibdrazzib#!/bin/bash # $Id: //open/farrago/sqlline#4 $ # Run Farrago as a standalone RMI server source ./defineFarragoRuntime.sh java ${SERVER_JAVA_ARGS} net.sf.farrago.server.FarragoVjdbcServer eigenbase-farrago-0.9.0/dbmanClient0000555000175000017500000000052511173714170017125 0ustar drazzibdrazzib#!/bin/bash # $Id: //open/dev/farrago/dbmanClient#2 $ # Run the hsqldb Database Manager tool as a client # to a Farrago server source ./defineFarragoRuntime.sh java ${CLIENT_JAVA_ARGS} org.hsqldb.util.DatabaseManagerSwing \ --driver net.sf.farrago.jdbc.client.FarragoVjdbcClientDriver \ --url jdbc:farrago:rmi://localhost \ --user sa \ $* eigenbase-farrago-0.9.0/src/0000755000175000017500000000000011173714170015546 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/0000755000175000017500000000000011173714170016334 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/0000755000175000017500000000000011173714170016744 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/0000755000175000017500000000000011173714170020365 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/0000755000175000017500000000000011173714170021267 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/0000755000175000017500000000000011173714170022534 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedNonDdl.java0000444000175000017500000002301311173714170031450 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedNonDdl.java#17 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.math.*; import java.sql.*; import java.sql.Date; import java.util.Calendar; import net.sf.farrago.session.*; import net.sf.farrago.type.*; /** * FarragoJdbcEnginePreparedNonDdl implements {@link * FarragoJdbcEnginePreparedStatement} when the statement is a query or DML. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedNonDdl.java#17 $ */ public class FarragoJdbcEnginePreparedNonDdl extends FarragoJdbcEnginePreparedStatement { //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcEnginePreparedNonDdl object. * * @param connection the connection creating this statement * @param stmtContext the underyling prepared FarragoSessionStmtContext * @param sql the text of the SQL statement */ FarragoJdbcEnginePreparedNonDdl( FarragoJdbcEngineConnection connection, FarragoSessionStmtContext stmtContext, String sql) { super(connection, stmtContext, sql); } //~ Methods ---------------------------------------------------------------- // implement PreparedStatement public boolean execute() throws SQLException { try { stmtContext.execute(); return (openCursorResultSet() != null); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement PreparedStatement public ResultSet executeQuery() throws SQLException { validateSession(); if (stmtContext.isPreparedDml()) { throw new SQLException(ERRMSG_NOT_A_QUERY + sql); } try { stmtContext.execute(); ResultSet resultSet = openCursorResultSet(); assert (resultSet != null); return resultSet; } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement PreparedStatement public int executeUpdate() throws SQLException { validateSession(); if (!stmtContext.isPreparedDml()) { throw new SQLException(ERRMSG_IS_A_QUERY + sql); } try { stmtContext.execute(); assert (stmtContext.getResultSet() == null); int count = getUpdateCount(); if (count == -1) { count = 0; } return count; } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement PreparedStatement public ResultSetMetaData getMetaData() throws SQLException { if (stmtContext.isPreparedDml()) { throw new SQLException(ERRMSG_NOT_A_QUERY + sql); } try { return new FarragoResultSetMetaData( stmtContext.getPreparedRowType()); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement PreparedStatement public ParameterMetaData getParameterMetaData() throws SQLException { try { return new FarragoParameterMetaData( stmtContext.getPreparedParamType()); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement PreparedStatement public void clearParameters() throws SQLException { try { stmtContext.clearParameters(); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } private void setDynamicParam( int parameterIndex, Object obj) throws SQLException { try { stmtContext.setDynamicParam(parameterIndex - 1, obj); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } private void setDynamicParam( int parameterIndex, Object obj, Calendar cal) throws SQLException { try { stmtContext.setDynamicParam(parameterIndex - 1, obj, cal); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement PreparedStatement public void setNull( int parameterIndex, int sqlType) throws SQLException { // REVIEW: use sqlType? setDynamicParam(parameterIndex, null); } // implement PreparedStatement public void setBoolean( int parameterIndex, boolean x) throws SQLException { setDynamicParam( parameterIndex, Boolean.valueOf(x)); } // implement PreparedStatement public void setByte( int parameterIndex, byte x) throws SQLException { setDynamicParam( parameterIndex, Byte.valueOf(x)); } // implement PreparedStatement public void setShort( int parameterIndex, short x) throws SQLException { setDynamicParam( parameterIndex, Short.valueOf(x)); } // implement PreparedStatement public void setInt( int parameterIndex, int x) throws SQLException { setDynamicParam( parameterIndex, Integer.valueOf(x)); } // implement PreparedStatement public void setLong( int parameterIndex, long x) throws SQLException { setDynamicParam( parameterIndex, Long.valueOf(x)); } // implement PreparedStatement public void setFloat( int parameterIndex, float x) throws SQLException { setDynamicParam( parameterIndex, Float.valueOf(x)); } // implement PreparedStatement public void setDouble( int parameterIndex, double x) throws SQLException { setDynamicParam( parameterIndex, Double.valueOf(x)); } // implement PreparedStatement public void setBigDecimal( int parameterIndex, BigDecimal x) throws SQLException { setDynamicParam(parameterIndex, x); } // implement PreparedStatement public void setString( int parameterIndex, String x) throws SQLException { setDynamicParam(parameterIndex, x); } // implement PreparedStatement public void setBytes( int parameterIndex, byte [] x) throws SQLException { setDynamicParam(parameterIndex, x); } // implement PreparedStatement public void setDate( int parameterIndex, Date x) throws SQLException { setDate( parameterIndex, x, Calendar.getInstance()); } // implement PreparedStatement public void setDate( int parameterIndex, Date x, Calendar cal) throws SQLException { setDynamicParam(parameterIndex, x, cal); } // implement PreparedStatement public void setTime( int parameterIndex, Time x) throws SQLException { setTime( parameterIndex, x, Calendar.getInstance()); } // implement PreparedStatement public void setTime( int parameterIndex, Time x, Calendar cal) throws SQLException { setDynamicParam(parameterIndex, x, cal); } // implement PreparedStatement public void setTimestamp( int parameterIndex, Timestamp x) throws SQLException { setTimestamp( parameterIndex, x, Calendar.getInstance()); } // implement PreparedStatement public void setTimestamp( int parameterIndex, Timestamp x, Calendar cal) throws SQLException { setDynamicParam(parameterIndex, x, cal); } // implement PreparedStatement public void setObject( int parameterIndex, Object x) throws SQLException { if (x instanceof java.util.Date) { setDynamicParam( parameterIndex, x, Calendar.getInstance()); } else { setDynamicParam(parameterIndex, x); } } } // End FarragoJdbcEnginePreparedNonDdl.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineConnection.java0000444000175000017500000005543111173714170030717 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineConnection.java#34 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.db.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.namespace.*; import net.sf.farrago.namespace.util.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.util.*; import org.eigenbase.jdbc4.*; import org.eigenbase.sql.*; import org.eigenbase.sql.parser.*; import org.eigenbase.util.*; /** * FarragoJdbcEngineConnection implements the {@link java.sql.Connection} * interface for the Farrago JDBC engine driver. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineConnection.java#34 $ */ public class FarragoJdbcEngineConnection extends Unwrappable implements FarragoConnection, FarragoSessionConnectionSource { //~ Instance fields -------------------------------------------------------- private FarragoSessionFactory sessionFactory; private FarragoSession session; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcEngineConnection object. * * @param url URL used to connect * @param info properties for this connection * @param sessionFactory FarragoSessionFactory governing this connection's * behavior */ public FarragoJdbcEngineConnection( String url, Properties info, FarragoSessionFactory sessionFactory) throws SQLException { this(sessionFactory.newSession(url, info)); this.sessionFactory = sessionFactory; try { initConnection(info); } catch (SQLException e) { close(); // prevent leak throw e; } } private FarragoJdbcEngineConnection( FarragoSession session) { this.session = session; session.setDatabaseMetaData( new FarragoJdbcEngineDatabaseMetaData(this)); session.setConnectionSource(this); } //~ Methods ---------------------------------------------------------------- public FarragoSession getSession() { return session; } // implement FarragoConnection public long getFarragoSessionId() { if ((session == null) || session.isClosed()) { return 0; } return session.getSessionInfo().getId(); } // implement Connection public boolean isClosed() throws SQLException { return (session == null); } // implement FarragoSessionConnectionSource public Connection newConnection() { return new FarragoJdbcEngineConnection( session.cloneSession(null)); } // implement Connection public void setAutoCommit(boolean autoCommit) throws SQLException { validateSession(); try { session.setAutoCommit(autoCommit); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public boolean getAutoCommit() throws SQLException { validateSession(); return session.isAutoCommit(); } // implement Connection public void setCatalog(String catalog) throws SQLException { // TODO return; // until implemented, JDBC API doc says to silently ignore } // implement Connection public String getCatalog() throws SQLException { validateSession(); return session.getSessionVariables().catalogName; } // implement Connection public void close() throws SQLException { if (session == null) { return; } try { try { if (session.isClosed()) { // Already closed internally by something like // a database shutdown; pop out now to avoid assertions. return; } session.closeAllocation(); if (session.isClone()) { return; } } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } sessionFactory.cleanupSessions(); } finally { session = null; } } public void commit() throws SQLException { validateSession(); try { session.commit(); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public Statement createStatement() throws SQLException { validateSession(); try { // FarragoSessionStmtContext created without a param def factory // because plain Statements cannot use dynamic parameters. return new FarragoJdbcEngineStatement( this, session.newStmtContext(null)); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public void rollback() throws SQLException { validateSession(); try { session.rollback(null); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public void rollback(Savepoint savepoint) throws SQLException { validateSession(); FarragoSessionSavepoint farragoSavepoint = validateSavepoint(savepoint); try { session.rollback(farragoSavepoint); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public void setTransactionIsolation(int level) throws SQLException { // TODO: implement this; dummied out for now to shut sqlline up } public int getTransactionIsolation() throws SQLException { if (getMetaData().supportsTransactions()) { return TRANSACTION_READ_UNCOMMITTED; } else { return TRANSACTION_NONE; } } // implement Connection public Savepoint setSavepoint() throws SQLException { validateSession(); try { return new FarragoJdbcEngineSavepoint(session.newSavepoint(null)); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public Savepoint setSavepoint(String name) throws SQLException { validateSession(); try { return new FarragoJdbcEngineSavepoint(session.newSavepoint(name)); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } private FarragoSessionSavepoint validateSavepoint(Savepoint savepoint) throws SQLException { if (!(savepoint instanceof FarragoJdbcEngineSavepoint)) { throw new SQLException("Savepoint class not recognized"); } return ((FarragoJdbcEngineSavepoint) savepoint).farragoSavepoint; } // implement Connection public void releaseSavepoint(Savepoint savepoint) throws SQLException { validateSession(); FarragoSessionSavepoint farragoSavepoint = validateSavepoint(savepoint); try { session.releaseSavepoint(farragoSavepoint); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } // implement Connection public DatabaseMetaData getMetaData() throws SQLException { validateSession(); return session.getDatabaseMetaData(); } // implement Connection public PreparedStatement prepareStatement(String sql) throws SQLException { validateSession(); FarragoSessionStmtContext stmtContext = null; try { stmtContext = session.newStmtContext(new FarragoJdbcEngineParamDefFactory()); stmtContext.prepare(sql, false); FarragoJdbcEnginePreparedStatement preparedStmt; if (!stmtContext.isPrepared()) { preparedStmt = new FarragoJdbcEnginePreparedDdl(this, stmtContext, sql); } else { preparedStmt = new FarragoJdbcEnginePreparedNonDdl(this, stmtContext, sql); stmtContext = null; } return preparedStmt; } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } finally { if (stmtContext != null) { stmtContext.unprepare(); } } } // implement Connection public PreparedStatement prepareStatement( String sql, int resultSetType, int resultSetConcurrency) throws SQLException { // NOTE jvs 3-May-2008: We don't currently throw // UnsupportedOperationException return prepareStatement(sql); } // implement Connection public PreparedStatement prepareStatement( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return prepareStatement(sql, resultSetType, resultSetConcurrency); } // implement Connection public PreparedStatement prepareStatement( String sql, int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS) { throw new UnsupportedOperationException(); } return prepareStatement(sql); } // implement Connection public PreparedStatement prepareStatement( String sql, int [] columnIndexes) throws SQLException { throw new UnsupportedOperationException(); } // implement Connection public PreparedStatement prepareStatement( String sql, String [] columnNames) throws SQLException { throw new UnsupportedOperationException(); } public void setHoldability(int holdability) throws SQLException { throw new UnsupportedOperationException(); } public int getHoldability() throws SQLException { return ResultSet.CLOSE_CURSORS_AT_COMMIT; } public void setReadOnly(boolean readOnly) throws SQLException { // TODO jvs 16-June-2006: Enforce read-only. For now we just ignore // it, since the JDBC javadoc says this is just a hint, and // some clients (such as Mondrian) choke if we throw an // exception. } public boolean isReadOnly() throws SQLException { return false; } public void setTypeMap(Map map) throws SQLException { throw new UnsupportedOperationException(); } public Map getTypeMap() throws SQLException { throw new UnsupportedOperationException(); } // implement Connection public SQLWarning getWarnings() throws SQLException { validateSession(); return session.getWarningQueue().getWarnings(); } // implement Connection public void clearWarnings() throws SQLException { validateSession(); session.getWarningQueue().clearWarnings(); } public Statement createStatement( int resultSetType, int resultSetConcurrency) throws SQLException { // NOTE jvs 3-May-2008: Rather than throwing // UnsupportedOperationException here and elsewhere when // clients ask for things we don't support, such as // scroll cursors, just ignore the modifiers. They'll // find out about it if they actually try to use the // feature. The reason for this is that often client applications // ask for things they never use, so being too strict // prevents them from working. return createStatement(); } public Statement createStatement( int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return createStatement(); } public String nativeSQL(String sql) throws SQLException { throw new UnsupportedOperationException(); } public CallableStatement prepareCall(String sql) throws SQLException { throw new UnsupportedOperationException(); } public CallableStatement prepareCall( String sql, int resultSetType, int resultSetConcurrency) throws SQLException { throw new UnsupportedOperationException(); } public CallableStatement prepareCall( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { throw new UnsupportedOperationException(); } /** * Performs additional setup based on connection property settings. * * @param info connection properties * * @throws SQLException */ protected void initConnection(Properties info) throws SQLException { String initialSchema = info.getProperty("schema"); if (initialSchema != null) { Statement stmt = this.createStatement(); try { stmt.executeUpdate("set schema '" + initialSchema + "'"); } finally { try { stmt.close(); } catch (SQLException e) { // allow executeUpdate() exception to propagate Util.swallow(e, null); } } } } protected void validateSession() throws SQLException { // REVIEW: hersker: 5/23/2007: if the session is closed, the // "session" var is null, and the session.wasKilled(), below, // will throw an NPE. Throwing "session closed" seems better. if (isClosed()) { throw FarragoJdbcEngineDriver.newSqlException( FarragoResource.instance().JdbcConnSessionClosed.ex()); } // REVIEW: SWZ: 4/19/2006: Some DDL can cause a shutdown. In that // event, the session is closed. FarragoTestCase doesn't handle // this and attempts to use methods that call this validation method. // Therefore, we only check for killed, not closed, sessions. This // may need to be modified if there are reasons for a session to be // closed out from under a connection other than killing. if (session.wasKilled()) { throw FarragoJdbcEngineDriver.newSqlException( FarragoResource.instance().JdbcConnSessionKilled.ex()); } } public String findMofId(String wrapperName) throws SQLException { validateSession(); FarragoDbSession session = (FarragoDbSession) getSession(); SqlIdentifier wrapperSqlIdent = new SqlIdentifier(wrapperName, SqlParserPos.ZERO); FemDataWrapper wrapper = FarragoCatalogUtil.getModelElementByName( session.getRepos().allOfType(FemDataWrapper.class), wrapperSqlIdent.getSimple()); if (wrapper != null) { if (!wrapper.isForeign()) { wrapper = null; } } if (wrapper != null) { return wrapper.refMofId(); } else { return null; } } public FarragoMedDataWrapperInfo getWrapper( String mofId, String libraryName, Properties options) throws SQLException { validateSession(); return new FleetingMedDataWrapperInfo(mofId, libraryName, options); } // // begin JDBC 4 methods // // implement Connection public Struct createStruct(String typeName, Object [] attributes) throws SQLException { throw new UnsupportedOperationException("createStruct"); } // implement Connection public Array createArrayOf(String typeName, Object [] elements) throws SQLException { throw new UnsupportedOperationException("createArrayOf"); } // implement Connection public Properties getClientInfo() throws SQLException { throw new UnsupportedOperationException("getClientInfo"); } // implement Connection public String getClientInfo(String name) throws SQLException { throw new UnsupportedOperationException("getClientInfo"); } // implement Connection public void setClientInfo(String name, String value) { throw new UnsupportedOperationException("setClientInfo"); } // implement Connection public void setClientInfo(Properties props) { throw new UnsupportedOperationException("setClientInfo"); } // implement Connection public boolean isValid(int timeout) { throw new UnsupportedOperationException("isValid"); } // implement Connection public SQLXML createSQLXML() throws SQLException { throw new UnsupportedOperationException("createSQLXML"); } // implement Connection public NClob createNClob() throws SQLException { throw new UnsupportedOperationException("createNClob"); } // implement Connection public Clob createClob() throws SQLException { throw new UnsupportedOperationException("createClob"); } // implement Connection public Blob createBlob() throws SQLException { throw new UnsupportedOperationException("createBlob"); } //~ Inner Classes ---------------------------------------------------------- // // end JDBC 4 methods // /** * Implementation of {@link FarragoMedDataWrapperInfo} which fleetingly * grabs a {@link FarragoMedDataWrapper} at the start of a call and unpins * it before the end of the call. */ private class FleetingMedDataWrapperInfo implements FarragoMedDataWrapperInfo { private final String mofId; private final String libraryName; private final Properties options; private FarragoDataWrapperCache dataWrapperCache; FleetingMedDataWrapperInfo( String mofId, String libraryName, Properties options) { this.mofId = mofId; this.libraryName = libraryName; this.options = (Properties) options.clone(); } private FarragoMedDataWrapper getWrapper() { assert (dataWrapperCache == null); final FarragoDbSession session = (FarragoDbSession) getSession(); final FarragoDatabase db = session.getDatabase(); final FarragoObjectCache sharedCache = db.getDataWrapperCache(); dataWrapperCache = new FarragoDataWrapperCache( session, sharedCache, db.getPluginClassLoader(), session.getRepos(), db.getFennelDbHandle(), null); final FarragoMedDataWrapper dataWrapper = dataWrapperCache.loadWrapper(mofId, libraryName, options); return dataWrapper; } private void closeWrapperCache() { dataWrapperCache.closeAllocation(); dataWrapperCache = null; } public DriverPropertyInfo [] getPluginPropertyInfo( Locale locale, Properties wrapperProps) { FarragoMedDataWrapper dataWrapper = getWrapper(); try { return dataWrapper.getPluginPropertyInfo(locale, wrapperProps); } finally { closeWrapperCache(); } } public DriverPropertyInfo [] getServerPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps) { FarragoMedDataWrapper dataWrapper = getWrapper(); try { return dataWrapper.getServerPropertyInfo( locale, wrapperProps, serverProps); } finally { closeWrapperCache(); } } public DriverPropertyInfo [] getColumnSetPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps) { FarragoMedDataWrapper dataWrapper = getWrapper(); try { return dataWrapper.getColumnSetPropertyInfo( locale, wrapperProps, serverProps, tableProps); } finally { closeWrapperCache(); } } public DriverPropertyInfo [] getColumnPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps, Properties columnProps) { FarragoMedDataWrapper dataWrapper = getWrapper(); try { return dataWrapper.getColumnPropertyInfo( locale, wrapperProps, serverProps, tableProps, columnProps); } finally { closeWrapperCache(); } } public boolean isForeign() { FarragoMedDataWrapper dataWrapper = getWrapper(); try { return dataWrapper.isForeign(); } finally { closeWrapperCache(); } } } } // End FarragoJdbcEngineConnection.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/package.html0000444000175000017500000000126311173714170025015 0ustar drazzibdrazzib Package net.sf.farrago.jdbc.engine Implements the Farrago JDBC driver as an SQL engine. This can be used directly (embedded into a 1-tier application) or as the server side in a client/server configuration.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/package.html#7 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedDdl.java0000444000175000017500000000610211173714170030775 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedDdl.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import net.sf.farrago.session.*; /** * FarragoJdbcEnginePreparedDdl implements {@link * FarragoJdbcEnginePreparedStatement} when the statement is DDL. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedDdl.java#11 $ */ public class FarragoJdbcEnginePreparedDdl extends FarragoJdbcEnginePreparedStatement { //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcEnginePreparedDdl object. * * @param connection the connection creating this statement * @param stmtContext the underyling FarragoSessionStmtContext (unprepared) * @param sql the text of the DDL statement */ FarragoJdbcEnginePreparedDdl( FarragoJdbcEngineConnection connection, FarragoSessionStmtContext stmtContext, String sql) { super(connection, stmtContext, sql); } //~ Methods ---------------------------------------------------------------- // implement PreparedStatement public boolean execute() throws SQLException { executeDdl(); return false; } // implement PreparedStatement public ResultSet executeQuery() throws SQLException { throw new SQLException(ERRMSG_NOT_A_QUERY + sql); } // implement PreparedStatement public int executeUpdate() throws SQLException { executeDdl(); return 0; } private void executeDdl() throws SQLException { // REVIEW: need to reset any context (like current schema) as it was // at the time of prepare? // NOTE: We fib and say this is direct execution. try { stmtContext.prepare(sql, true); assert (!stmtContext.isPrepared()); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } } // End FarragoJdbcEnginePreparedDdl.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcRoutineDriver.java0000444000175000017500000000661411173714170030272 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcRoutineDriver.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import java.util.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.resource.*; import net.sf.farrago.runtime.*; import net.sf.farrago.session.*; /** * FarragoJdbcRoutineDriver implements the JDBC driver used for default * connections from user-defined routines. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcRoutineDriver.java#10 $ */ public class FarragoJdbcRoutineDriver extends FarragoAbstractJdbcDriver implements Driver { // NOTE jvs 19-Jan-2005: let FarragoJdbcEngineDriver register us, // since no one else should be referencing us directly //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcRoutineDriver object. */ public FarragoJdbcRoutineDriver() { } //~ Methods ---------------------------------------------------------------- // implement FarragoAbstractJdbcDriver public String getBaseUrl() { return "jdbc:default:connection"; } // implement FarragoAbstractJdbcDriver public String getUrlPrefix() { return getBaseUrl(); } // implement Driver public Connection connect( String url, Properties info) throws SQLException { if (!acceptsURL(url)) { return null; } try { if (!url.equals(getBaseUrl())) { throw FarragoResource.instance().JdbcInvalidUrl.ex(url); } return FarragoRuntimeContext.newConnection(); } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } /** * Converts a connection returned via URL "jdbc:default:connection" to a * FarragoSession. This can be used by user-defined routines to gain * internal access to Farrago. Use with caution. * * @param conn connection * * @return session */ public static FarragoSession getSessionForConnection(Connection conn) throws SQLException { try { return ((FarragoJdbcEngineConnection) conn).getSession(); } catch (ClassCastException ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } } } // End FarragoJdbcRoutineDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedStatement.java0000444000175000017500000003750611173714170032252 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedStatement.java#14 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.io.*; import java.math.*; import java.net.*; import java.sql.*; import java.sql.Date; import java.util.*; import net.sf.farrago.session.*; import org.eigenbase.jdbc4.*; /** * FarragoJdbcEnginePreparedStatement is an abstract base for Farrago * implementations of {@link java.sql.PreparedStatement}. Subclasses define * details of preparation for DDL, DML, and queries. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEnginePreparedStatement.java#14 $ */ public abstract class FarragoJdbcEnginePreparedStatement extends FarragoJdbcEngineStatement implements PreparedStatement { //~ Static fields/initializers --------------------------------------------- protected static final String ERRMSG_ALREADY_PREPARED = "Statement already prepared"; //~ Instance fields -------------------------------------------------------- protected String sql; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcEnginePreparedStatement object. * * @param connection the connection creating this statement * @param stmtContext underlying FarragoSessionStmtContext * @param sql the text of the SQL statement */ protected FarragoJdbcEnginePreparedStatement( FarragoJdbcEngineConnection connection, FarragoSessionStmtContext stmtContext, String sql) { super(connection, stmtContext); this.sql = sql; } //~ Methods ---------------------------------------------------------------- // implement PreparedStatement public ResultSetMetaData getMetaData() throws SQLException { throw new SQLException(ERRMSG_NOT_A_QUERY + sql); } // implement PreparedStatement public ParameterMetaData getParameterMetaData() throws SQLException { throw new SQLException(ERRMSG_NOT_A_QUERY + sql); } // implement PreparedStatement public void clearParameters() throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setNull( int parameterIndex, int sqlType) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setBoolean( int parameterIndex, boolean x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setByte( int parameterIndex, byte x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setShort( int parameterIndex, short x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setInt( int parameterIndex, int x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setLong( int parameterIndex, long x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setFloat( int parameterIndex, float x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setDouble( int parameterIndex, double x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setBigDecimal( int parameterIndex, BigDecimal x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setString( int parameterIndex, String x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setBytes( int parameterIndex, byte [] x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setDate( int parameterIndex, Date x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setTime( int parameterIndex, Time x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setTimestamp( int parameterIndex, Timestamp x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setAsciiStream( int parameterIndex, InputStream x, int length) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setUnicodeStream( int parameterIndex, InputStream x, int length) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setBinaryStream( int parameterIndex, InputStream x, int length) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setObject( int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setObject( int parameterIndex, Object x, int targetSqlType) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setObject( int parameterIndex, Object x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setCharacterStream( int parameterIndex, Reader reader, int length) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setRef( int i, Ref x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setBlob( int i, Blob x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setClob( int i, Clob x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setArray( int i, Array x) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setDate( int parameterIndex, Date x, Calendar cal) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setTime( int parameterIndex, Time x, Calendar cal) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setTimestamp( int parameterIndex, Timestamp x, Calendar cal) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setNull( int paramIndex, int sqlType, String typeName) throws SQLException { throw new UnsupportedOperationException(); } // implement PreparedStatement public void setURL( int parameterIndex, URL x) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement: disallow for PreparedStatements public void addBatch() throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public void clearBatch() throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public void setEscapeProcessing(boolean enable) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public void addBatch(String sql) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public int [] executeBatch() throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public ResultSet executeQuery(String sql) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public boolean execute(String sql) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public boolean execute( String sql, int autoGeneratedKeys) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public boolean execute( String sql, int [] columnIndexes) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public boolean execute( String sql, String [] columnNames) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public int executeUpdate(String sql) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public int executeUpdate( String sql, int autoGeneratedKeys) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public int executeUpdate( String sql, int [] columnIndexes) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // implement Statement: disallow for PreparedStatements public int executeUpdate( String sql, String [] columnNames) throws SQLException { throw new SQLException(ERRMSG_ALREADY_PREPARED); } // // begin JDBC 4 methods // // implement PreparedStatement public void setCharacterStream(int i, Reader reader) throws SQLException { throw new UnsupportedOperationException("setCharacterStream"); } // implement PreparedStatement public void setCharacterStream(int i, Reader reader, long len) throws SQLException { throw new UnsupportedOperationException("setCharacterStream"); } // implement PreparedStatement public void setNCharacterStream(int i, Reader reader) throws SQLException { throw new UnsupportedOperationException("setNCharacterStream"); } // implement PreparedStatement public void setNCharacterStream(int i, Reader reader, long len) throws SQLException { throw new UnsupportedOperationException("setNCharacterStream"); } // implement PreparedStatement public void setClob(int i, Reader reader) throws SQLException { throw new UnsupportedOperationException("setClob"); } // implement PreparedStatement public void setClob(int i, Reader reader, long len) throws SQLException { throw new UnsupportedOperationException("setClob"); } // implement PreparedStatement public void setNClob(int i, Reader reader) throws SQLException { throw new UnsupportedOperationException("setNClob"); } // implement PreparedStatement public void setNClob(int i, NClob nclob) throws SQLException { throw new UnsupportedOperationException("setNClob"); } // implement PreparedStatement public void setNClob(int i, Reader reader, long len) throws SQLException { throw new UnsupportedOperationException("setNClob"); } // implement PreparedStatement public void setBlob(int i, InputStream inputStream) throws SQLException { throw new UnsupportedOperationException("setBlob"); } // implement PreparedStatement public void setBlob(int i, InputStream inputStream, long len) throws SQLException { throw new UnsupportedOperationException("setBlob"); } // implement PreparedStatement public void setBinaryStream(int i, InputStream inputStream) throws SQLException { throw new UnsupportedOperationException("setBinaryStream"); } // implement PreparedStatement public void setBinaryStream(int i, InputStream inputStream, long len) throws SQLException { throw new UnsupportedOperationException("setBinaryStream"); } // implement PreparedStatement public void setAsciiStream(int i, InputStream inputStream) throws SQLException { throw new UnsupportedOperationException("setAsciiStream"); } // implement PreparedStatement public void setAsciiStream(int i, InputStream inputStream, long len) throws SQLException { throw new UnsupportedOperationException("setAsciiStream"); } // implement PreparedStatement public void setSQLXML(int i, SQLXML sqlxml) throws SQLException { throw new UnsupportedOperationException("setSQLXML"); } // implement PreparedStatement public void setNString(int i, String nstring) throws SQLException { throw new UnsupportedOperationException("setNString"); } // implement PreparedStatement public void setRowId(int i, RowId rowid) throws SQLException { throw new UnsupportedOperationException("setRowId"); } // // end JDBC 4 methods // } // End FarragoJdbcEnginePreparedStatement.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineParamDefFactory.java0000444000175000017500000000442011173714170031617 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineParamDefFactory.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import net.sf.farrago.jdbc.param.*; import net.sf.farrago.session.*; import org.eigenbase.reltype.*; /** * FarragoJdbcEngineParamDefFactory implements {@link * FarragoSessionStmtParamDefFactory} for JDBC. * * @author stephan * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineParamDefFactory.java#10 $ */ public class FarragoJdbcEngineParamDefFactory implements FarragoSessionStmtParamDefFactory { //~ Methods ---------------------------------------------------------------- // Implement FarragoSessionStmtParamDefFactory public FarragoSessionStmtParamDef newParamDef( String paramName, RelDataType type) { FarragoParamFieldMetaData paramMetaData = FarragoParamFieldMetaDataFactory.newParamFieldMetaData( type, ParameterMetaData.parameterModeIn); FarragoJdbcParamDef param = FarragoJdbcParamDefFactory.instance.newParamDef( paramName, paramMetaData, false); return new FarragoJdbcEngineParamDef(param, type); } } // End FarragoJdbcEngineParamDefFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineParamDef.java0000444000175000017500000000543211173714170030273 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineParamDef.java#9 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.util.*; import net.sf.farrago.jdbc.param.*; import net.sf.farrago.session.*; import org.eigenbase.reltype.*; /** * Enforces constraints on parameters. The constraints are: * *

    *
  1. Ensures that null values cannot be inserted into not-null columns. *
  2. Ensures that value is the right type. *
  3. Ensures that the value is within range. For example, you can't insert a * 10001 into a DECIMAL(5) column. *
* *

TODO: Actually enfore these constraints. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineParamDef.java#9 $ */ class FarragoJdbcEngineParamDef implements FarragoSessionStmtParamDef { //~ Instance fields -------------------------------------------------------- final FarragoJdbcParamDef param; final RelDataType type; //~ Constructors ----------------------------------------------------------- FarragoJdbcEngineParamDef(FarragoJdbcParamDef param, RelDataType type) { this.param = param; this.type = type; } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public String getParamName() { return param.getParamName(); } // implement FarragoSessionStmtParamDef public RelDataType getParamType() { return type; } // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { return param.scrubValue(x); } // implement FarragoSessionStmtParamDef public Object scrubValue(Object x, Calendar cal) { return param.scrubValue(x, cal); } } // End FarragoJdbcEngineParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcServerDriver.java0000444000175000017500000000404111173714170030103 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcServerDriver.java#13 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import net.sf.farrago.session.*; /** * FarragoJdbcServerDriver defines the interface which must be implemented by * JDBC drivers which can be used to implement {@link * net.sf.farrago.server.FarragoRmiJdbcServer}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcServerDriver.java#13 $ */ public interface FarragoJdbcServerDriver extends Driver { //~ Methods ---------------------------------------------------------------- /** * Creates a new FarragoSessionFactory which will govern the behavior of * connections established through this driver. * * @return new factory */ public FarragoSessionFactory newSessionFactory(); /** * @return the base JDBC URL for this driver; subclassing drivers can * override this to customize the URL scheme */ public String getBaseUrl(); } // End FarragoJdbcServerDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoParamFieldMetaDataFactory.java0000444000175000017500000000560611173714170031643 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoParamFieldMetaDataFactory.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2006-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.util.*; import net.sf.farrago.jdbc.param.*; import net.sf.farrago.runtime.*; import org.eigenbase.reltype.*; /** * Factory class for creating the per-column metadata passed to the client * driver for its ParameterMetaData implementation. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoParamFieldMetaDataFactory.java#8 $ * @since March 3, 2006 */ public class FarragoParamFieldMetaDataFactory { //~ Constructors ----------------------------------------------------------- /** * private constructor to prevent instantiation. */ private FarragoParamFieldMetaDataFactory() { } //~ Methods ---------------------------------------------------------------- public static FarragoParamFieldMetaData newParamFieldMetaData( RelDataType type, int mode) { return FarragoRuntimeJdbcUtil.newParamFieldMetaData(type, mode); } /** * Determines the parameter column meta data from the rowType * * @param rowType Row type * * @return Parameter column metadata */ public static FarragoParamFieldMetaData [] newParamMetaData( RelDataType rowType, int mode) { FarragoParamFieldMetaData [] metaData; List fieldTypes = rowType.getFieldList(); int colCnt = fieldTypes.size(); metaData = new FarragoParamFieldMetaData[colCnt]; for (int i = 0; i < colCnt; ++i) { RelDataTypeField f = fieldTypes.get(i); RelDataType relType = f.getType(); FarragoParamFieldMetaData meta = newParamFieldMetaData(relType, mode); metaData[i] = meta; } return metaData; } } // End FarragoParamFieldMetaDataFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoUnregisteredJdbcEngineDriver.java0000444000175000017500000001051511173714170032426 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoUnregisteredJdbcEngineDriver.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import java.util.*; import java.util.logging.*; import net.sf.farrago.db.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; /** * FarragoJdbcEngineDriver implements the Farrago engine/server side of the * {@link java.sql.Driver} interface. It does not register itself; for that, use * {@link FarragoJdbcEngineDriver}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoUnregisteredJdbcEngineDriver.java#7 $ */ public abstract class FarragoUnregisteredJdbcEngineDriver extends FarragoAbstractJdbcDriver implements FarragoJdbcServerDriver { //~ Static fields/initializers --------------------------------------------- private static final Logger tracer = FarragoTrace.getFarragoJdbcEngineDriverTracer(); static { // NOTE jvs 29-July-2006: Even though we don't register ourselves, // we do register the loopback driver, because that always needs // to be registered regardless of which driver is being used to // access the engine from outside. new FarragoJdbcRoutineDriver().register(); } //~ Methods ---------------------------------------------------------------- // implement FarragoAbstractJdbcDriver public String getUrlPrefix() { return getBaseUrl(); } // implement Driver public Connection connect( String url, Properties info) throws SQLException { if (!acceptsURL(url)) { return null; } // connection property precedence: // connect string (URI), info props, connection defaults // don't modify user's properties: // copy input props backed by connection defaults, // move any params from the URI to the properties Properties driverProps = applyDefaultConnectionProps(info); String driverUrl = parseConnectionParams(url, driverProps); try { if (driverUrl.equals(getBaseUrl()) || driverUrl.equals(getClientUrl())) { return new FarragoJdbcEngineConnection( driverUrl, driverProps, newSessionFactory()); } else { throw FarragoResource.instance().JdbcInvalidUrl.ex(driverUrl); } } catch (Throwable ex) { throw newSqlException(ex); } } // implement FarragoJdbcServerDriver public FarragoSessionFactory newSessionFactory() { return FarragoDatabase.newSessionFactory(); } /** * Converter from any Throwable to SQLException. * * @param ex Throwable to be converted * * @return ex as a SQLException */ static SQLException newSqlException(Throwable ex) { return FarragoJdbcUtil.newSqlException(ex, tracer); } /** * Creates a new SQLException from the message. * * @param message detail message, the reason for this exception * * @return message as a SQLException */ static SQLException newSqlException(String message) { return FarragoJdbcUtil.newSqlException(message, tracer); } } // End FarragoUnregisteredJdbcEngineDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineSavepoint.java0000444000175000017500000000502411173714170030561 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineSavepoint.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import net.sf.farrago.fem.fennel.*; import net.sf.farrago.session.*; /** * FarragoJdbcEngineSavepoint implements the {@link java.sql.Savepoint} * interface for Farrago. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineSavepoint.java#11 $ */ public class FarragoJdbcEngineSavepoint implements Savepoint { //~ Instance fields -------------------------------------------------------- FarragoSessionSavepoint farragoSavepoint; //~ Constructors ----------------------------------------------------------- FarragoJdbcEngineSavepoint(FarragoSessionSavepoint farragoSavepoint) { this.farragoSavepoint = farragoSavepoint; } //~ Methods ---------------------------------------------------------------- // implement Savepoint public int getSavepointId() throws SQLException { if (farragoSavepoint.getName() != null) { throw new SQLException("Can't getSavepointId for named Savepoint"); } return farragoSavepoint.getId(); } // implement Savepoint public String getSavepointName() throws SQLException { if (farragoSavepoint.getName() == null) { throw new SQLException( "Can't getSavepointName for unnamed Savepoint"); } return farragoSavepoint.getName(); } } // End FarragoJdbcEngineSavepoint.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineStatement.java0000444000175000017500000003277211173714170030567 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineStatement.java#25 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.sql.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import org.eigenbase.jdbc4.*; import org.eigenbase.util14.*; /** * FarragoJdbcEngineStatement implements the {@link java.sql.Statement} * interface for the Farrago JDBC driver, including extensions from {@link * net.sf.farrago.jdbc.FarragoStatement}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineStatement.java#25 $ */ public class FarragoJdbcEngineStatement extends Unwrappable implements FarragoStatement { //~ Instance fields -------------------------------------------------------- /** * Connection through which this stmt was created. */ protected FarragoJdbcEngineConnection connection; /** * Underlying statement context. */ protected FarragoSessionStmtContext stmtContext; /** * @see Statement#setMaxRows */ private int maxRows; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcEngineStatement object. * * @param connection the connection creating this statement * @param stmtContext underlying FarragoSessionStmtContext */ FarragoJdbcEngineStatement( FarragoJdbcEngineConnection connection, FarragoSessionStmtContext stmtContext) { this.connection = connection; this.stmtContext = stmtContext; } //~ Methods ---------------------------------------------------------------- // implement Statement public void setEscapeProcessing(boolean enable) throws SQLException { // TODO: } // implement Statement public boolean getMoreResults() throws SQLException { stmtContext.closeResultSet(); return false; } // implement Statement public int getUpdateCount() throws SQLException { return (int) stmtContext.getUpdateCount(); } // implement Statement public boolean execute(String sql) throws SQLException { validateSession(); boolean unprepare = true; try { stmtContext.prepare(sql, true); if (stmtContext.isPrepared()) { stmtContext.execute(); if (openCursorResultSet() != null) { unprepare = false; return true; } else { return false; } } else { return false; } } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } finally { if (unprepare) { stmtContext.unprepare(); } else { // REVIEW: make sure everything is going to get // deallocated correctly when result set is closed } } } // implement Statement public int executeUpdate(String sql) throws SQLException { validateSession(); try { stmtContext.prepare(sql, true); if (stmtContext.isPrepared()) { if (!stmtContext.isPreparedDml()) { throw new SQLException(ERRMSG_IS_A_QUERY + sql); } stmtContext.execute(); assert (stmtContext.getResultSet() == null); int count = (int) stmtContext.getUpdateCount(); if (count == -1) { count = 0; } return count; } else { return 0; } } catch (SQLException ex) { throw ex; } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } finally { stmtContext.unprepare(); } } // implement Statement public ResultSet executeQuery(String sql) throws SQLException { validateSession(); boolean unprepare = true; try { stmtContext.prepare(sql, true); if (!stmtContext.isPrepared() || stmtContext.isPreparedDml()) { throw FarragoJdbcEngineDriver.newSqlException( ERRMSG_NOT_A_QUERY + sql); } stmtContext.execute(); ResultSet resultSet = openCursorResultSet(); assert (resultSet != null); unprepare = false; return resultSet; } catch (SQLException ex) { throw ex; } catch (Throwable ex) { throw FarragoJdbcEngineDriver.newSqlException(ex); } finally { if (unprepare) { stmtContext.unprepare(); } else { // REVIEW: make sure everything is going to get // deallocated correctly when result set is closed } } } // implement Statement public Connection getConnection() throws SQLException { return connection; } // implement Statement public void setCursorName(String name) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void setFetchDirection(int direction) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int getFetchDirection() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void setFetchSize(int rows) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int getFetchSize() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public ResultSet getGeneratedKeys() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void setMaxFieldSize(int max) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int getMaxFieldSize() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void setMaxRows(int max) throws SQLException { if (max < 0) { throw FarragoJdbcEngineDriver.newSqlException( ERRMSG_REQ_NON_NEG + "max=" + max); } maxRows = max; } // implement Statement public int getMaxRows() throws SQLException { return maxRows; } // implement Statement public boolean getMoreResults(int current) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void setQueryTimeout(int seconds) throws SQLException { // Statement API specifies must throw for negative timeout if (seconds < 0) { throw FarragoJdbcEngineDriver.newSqlException( ERRMSG_REQ_NON_NEG + "seconds=" + seconds); } stmtContext.setQueryTimeout(seconds * 1000); } // implement Statement public int getQueryTimeout() throws SQLException { int timeoutMillis = stmtContext.getQueryTimeout(); if ((timeoutMillis > 0) && (timeoutMillis < 1000)) { // Don't let 1ms become 0s (because that means no timeout). timeoutMillis = 1000; } return timeoutMillis / 1000; } protected ResultSet openCursorResultSet() { ResultSet resultSet = stmtContext.getResultSet(); if (resultSet == null) { return null; } if (resultSet instanceof AbstractResultSet) { AbstractResultSet abstractResultSet = (AbstractResultSet) resultSet; abstractResultSet.setMaxRows(maxRows); } return resultSet; } // implement Statement public ResultSet getResultSet() throws SQLException { return stmtContext.getResultSet(); } // implement Statement public int getResultSetConcurrency() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int getResultSetHoldability() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int getResultSetType() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void addBatch(String sql) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public void cancel() throws SQLException { if (stmtContext != null) { stmtContext.cancel(); } } // implement Statement public void clearBatch() throws SQLException { } // implement Statement public void close() throws SQLException { try { if (stmtContext != null) { stmtContext.closeAllocation(); } } finally { stmtContext = null; } } // implement Statement public boolean execute( String sql, int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys != NO_GENERATED_KEYS) { throw new UnsupportedOperationException(); } return execute(sql); } // implement Statement public boolean execute( String sql, int [] columnIndexes) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public boolean execute( String sql, String [] columnNames) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int [] executeBatch() throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int executeUpdate( String sql, int autoGeneratedKeys) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int executeUpdate( String sql, int [] columnIndexes) throws SQLException { throw new UnsupportedOperationException(); } // implement Statement public int executeUpdate( String sql, String [] columnNames) throws SQLException { throw new UnsupportedOperationException(); } // implement FarragoStatement public long getFarragoExecutingStmtId() { if (stmtContext == null) { return 0; } FarragoSessionExecutingStmtInfo info = stmtContext.getExecutingStmtInfo(); if (info == null) { return 0; } return info.getId(); } // implement Statement public SQLWarning getWarnings() throws SQLException { if (stmtContext == null) { return null; } return stmtContext.getWarningQueue().getWarnings(); } // implement Statement public void clearWarnings() throws SQLException { if (stmtContext == null) { return; } stmtContext.getWarningQueue().clearWarnings(); } /** * Validates statement's session and throws if session closed. * * @throws SQLException {@link FarragoResource#JdbcConnSessionClosed} */ protected void validateSession() throws SQLException { final FarragoSession sess = stmtContext.getSession(); if (sess.isClosed()) { throw FarragoJdbcEngineDriver.newSqlException( FarragoResource.instance().JdbcConnSessionClosed.ex()); } } // // begin JDBC 4 methods // // implement Statement public boolean isPoolable() throws SQLException { return false; } // implement Statement public void setPoolable(boolean poolable) throws SQLException { throw new UnsupportedOperationException("setPoolable"); } // implement Statement public boolean isClosed() throws SQLException { throw new UnsupportedOperationException("isClosed"); } // // end JDBC 4 methods // } // End FarragoJdbcEngineStatement.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineDatabaseMetaData.java0000444000175000017500000012145611173714170031726 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineDatabaseMetaData.java#35 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; import java.io.*; import java.sql.*; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.release.*; import net.sf.farrago.session.*; import org.eigenbase.jdbc4.*; import org.eigenbase.resource.*; import org.eigenbase.sql.*; /** * FarragoJdbcEngineDatabaseMetaData implements the {@link * java.sql.DatabaseMetaData} interface with Farrago specifics. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineDatabaseMetaData.java#35 $ */ public class FarragoJdbcEngineDatabaseMetaData extends Unwrappable implements DatabaseMetaData { //~ Instance fields -------------------------------------------------------- private FarragoJdbcEngineConnection connection; private FarragoRepos repos; private String jdbcKeywords; //~ Constructors ----------------------------------------------------------- protected FarragoJdbcEngineDatabaseMetaData( FarragoJdbcEngineConnection connection) { this.connection = connection; repos = connection.getSession().getRepos(); } //~ Methods ---------------------------------------------------------------- // implement DatabaseMetaData public boolean allProceduresAreCallable() throws SQLException { return true; } // implement DatabaseMetaData public boolean allTablesAreSelectable() throws SQLException { return true; } // implement DatabaseMetaData public String getURL() throws SQLException { return connection.getSession().getUrl(); } // implement DatabaseMetaData public String getUserName() throws SQLException { // REVIEW jvs 25-June-2005: should this be the current user // or the session user? return connection.getSession().getSessionVariables().currentUserName; } // implement DatabaseMetaData public boolean isReadOnly() throws SQLException { return false; } // implement DatabaseMetaData public boolean nullsAreSortedHigh() throws SQLException { return false; } // implement DatabaseMetaData public boolean nullsAreSortedLow() throws SQLException { return true; } // implement DatabaseMetaData public boolean nullsAreSortedAtStart() throws SQLException { return false; } // implement DatabaseMetaData public boolean nullsAreSortedAtEnd() throws SQLException { return false; } // implement DatabaseMetaData public String getDatabaseProductName() throws SQLException { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.productName.get(); } // implement DatabaseMetaData public String getDatabaseProductVersion() throws SQLException { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return "" + props.productVersionMajor.get() + "." + props.productVersionMinor.get() + "." + props.productVersionPoint.get(); } // implement DatabaseMetaData public int getDatabaseMajorVersion() throws SQLException { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.productVersionMajor.get(); } // implement DatabaseMetaData public int getDatabaseMinorVersion() throws SQLException { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.productVersionMinor.get(); } // implement DatabaseMetaData public int getJDBCMajorVersion() throws SQLException { return 3; } // implement DatabaseMetaData public int getJDBCMinorVersion() throws SQLException { return 0; } // implement DatabaseMetaData public String getDriverName() throws SQLException { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.jdbcDriverName.get(); } // implement DatabaseMetaData public String getDriverVersion() throws SQLException { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return "" + props.jdbcDriverVersionMajor.get() + "." + props.jdbcDriverVersionMinor.get(); } // implement DatabaseMetaData public int getDriverMajorVersion() { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.jdbcDriverVersionMajor.get(); } // implement DatabaseMetaData public int getDriverMinorVersion() { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.jdbcDriverVersionMinor.get(); } // implement DatabaseMetaData public boolean usesLocalFiles() throws SQLException { return false; } // implement DatabaseMetaData public boolean usesLocalFilePerTable() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsMixedCaseIdentifiers() throws SQLException { return false; } // implement DatabaseMetaData public boolean storesUpperCaseIdentifiers() throws SQLException { return true; } // implement DatabaseMetaData public boolean storesLowerCaseIdentifiers() throws SQLException { return false; } // implement DatabaseMetaData public boolean storesMixedCaseIdentifiers() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { return true; } // implement DatabaseMetaData public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { return false; } // implement DatabaseMetaData public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { return false; } // implement DatabaseMetaData public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { return false; } // implement DatabaseMetaData public String getIdentifierQuoteString() throws SQLException { return "\""; } // implement DatabaseMetaData public String getSQLKeywords() throws SQLException { if (jdbcKeywords == null) { FarragoSessionParser parser = connection.getSession().getPersonality().newParser( connection.getSession()); jdbcKeywords = parser.getJdbcKeywords(); } return jdbcKeywords; } // implement DatabaseMetaData public String getNumericFunctions() throws SQLException { return SqlJdbcFunctionCall.getNumericFunctions(); } // implement DatabaseMetaData public String getStringFunctions() throws SQLException { return SqlJdbcFunctionCall.getStringFunctions(); } // implement DatabaseMetaData public String getSystemFunctions() throws SQLException { return SqlJdbcFunctionCall.getSystemFunctions(); } // implement DatabaseMetaData public String getTimeDateFunctions() throws SQLException { return SqlJdbcFunctionCall.getTimeDateFunctions(); } // implement DatabaseMetaData public String getSearchStringEscape() throws SQLException { return "\\"; } // implement DatabaseMetaData public String getExtraNameCharacters() throws SQLException { return ""; } // implement DatabaseMetaData public boolean supportsAlterTableWithAddColumn() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsAlterTableWithDropColumn() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsColumnAliasing() throws SQLException { return true; } // implement DatabaseMetaData public boolean nullPlusNonNullIsNull() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsConvert() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsConvert( int fromType, int toType) throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsTableCorrelationNames() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsDifferentTableCorrelationNames() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsExpressionsInOrderBy() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsOrderByUnrelated() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsGroupBy() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsGroupByUnrelated() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsGroupByBeyondSelect() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsLikeEscapeClause() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsMultipleResultSets() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsMultipleTransactions() throws SQLException { return supportsTransactions(); } // implement DatabaseMetaData public boolean supportsNonNullableColumns() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsMinimumSQLGrammar() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsCoreSQLGrammar() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsExtendedSQLGrammar() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsANSI92EntryLevelSQL() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsANSI92IntermediateSQL() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsANSI92FullSQL() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsIntegrityEnhancementFacility() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsOuterJoins() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsFullOuterJoins() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsLimitedOuterJoins() throws SQLException { return true; } // implement DatabaseMetaData public String getSchemaTerm() throws SQLException { return "schema"; } // implement DatabaseMetaData public String getProcedureTerm() throws SQLException { return "routine"; } // implement DatabaseMetaData public String getCatalogTerm() throws SQLException { return "catalog"; } // implement DatabaseMetaData public boolean isCatalogAtStart() throws SQLException { return true; } // implement DatabaseMetaData public String getCatalogSeparator() throws SQLException { return "."; } // implement DatabaseMetaData public boolean supportsSchemasInDataManipulation() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSchemasInProcedureCalls() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSchemasInTableDefinitions() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSchemasInIndexDefinitions() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsCatalogsInDataManipulation() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsCatalogsInProcedureCalls() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsCatalogsInTableDefinitions() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsCatalogsInIndexDefinitions() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsPositionedDelete() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsPositionedUpdate() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsSelectForUpdate() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsStoredProcedures() throws SQLException { // TODO jvs 23-Mar-2005: need to support JDBC escape syntax return false; } // implement DatabaseMetaData public boolean supportsSubqueriesInComparisons() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSubqueriesInExists() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSubqueriesInIns() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsSubqueriesInQuantifieds() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsCorrelatedSubqueries() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsUnion() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsUnionAll() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsOpenCursorsAcrossCommit() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsOpenCursorsAcrossRollback() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsOpenStatementsAcrossCommit() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsOpenStatementsAcrossRollback() throws SQLException { return true; } // implement DatabaseMetaData public int getMaxBinaryLiteralLength() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxCharLiteralLength() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxColumnNameLength() throws SQLException { return repos.getIdentifierPrecision(); } // implement DatabaseMetaData public int getMaxColumnsInGroupBy() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxColumnsInIndex() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxColumnsInOrderBy() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxColumnsInSelect() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxColumnsInTable() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxConnections() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxCursorNameLength() throws SQLException { return repos.getIdentifierPrecision(); } // implement DatabaseMetaData public int getMaxIndexLength() throws SQLException { // TODO return 0; } // implement DatabaseMetaData public int getMaxSchemaNameLength() throws SQLException { return repos.getIdentifierPrecision(); } // implement DatabaseMetaData public int getMaxProcedureNameLength() throws SQLException { return repos.getIdentifierPrecision(); } // implement DatabaseMetaData public int getMaxCatalogNameLength() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxRowSize() throws SQLException { // TODO return 0; } // implement DatabaseMetaData public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { return false; } // implement DatabaseMetaData public int getMaxStatementLength() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxStatements() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxTableNameLength() throws SQLException { return repos.getIdentifierPrecision(); } // implement DatabaseMetaData public int getMaxTablesInSelect() throws SQLException { return 0; } // implement DatabaseMetaData public int getMaxUserNameLength() throws SQLException { return repos.getIdentifierPrecision(); } // implement DatabaseMetaData public int getDefaultTransactionIsolation() throws SQLException { if (supportsTransactions()) { return Connection.TRANSACTION_READ_UNCOMMITTED; } else { return Connection.TRANSACTION_NONE; } } // implement DatabaseMetaData public boolean supportsTransactions() throws SQLException { return connection.getSession().getPersonality().supportsFeature( EigenbaseResource.instance().SQLFeature_E151); } // implement DatabaseMetaData public boolean supportsTransactionIsolationLevel(int level) throws SQLException { return supportsTransactions() && (level == Connection.TRANSACTION_READ_UNCOMMITTED); } // implement DatabaseMetaData public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsDataManipulationTransactionsOnly() throws SQLException { return true; } // implement DatabaseMetaData public boolean dataDefinitionCausesTransactionCommit() throws SQLException { return true; } // implement DatabaseMetaData public boolean dataDefinitionIgnoredInTransactions() throws SQLException { return false; } // implement DatabaseMetaData public ResultSet getProcedures( String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.procedures_view"); queryBuilder.addExact("procedure_cat", catalog); queryBuilder.addPattern("procedure_schem", schemaPattern); queryBuilder.addPattern("procedure_name", procedureNamePattern); queryBuilder.addOrderBy("procedure_schem,procedure_name,procedure_cat"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getProcedureColumns( String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.procedure_columns_view"); queryBuilder.addExact("procedure_cat", catalog); queryBuilder.addPattern("procedure_schem", schemaPattern); queryBuilder.addPattern("procedure_name", procedureNamePattern); queryBuilder.addPattern("column_name", columnNamePattern); queryBuilder.addOrderBy( "procedure_schem,procedure_name,column_ordinal,procedure_cat"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getTables( String catalog, String schemaPattern, String tableNamePattern, String [] types) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.tables_view"); queryBuilder.addExact("table_cat", catalog); queryBuilder.addPattern("table_schem", schemaPattern); queryBuilder.addPattern("table_name", tableNamePattern); queryBuilder.addInList("table_type", types); queryBuilder.addOrderBy("table_type,table_schem,table_name,table_cat"); return queryBuilder.execute(); } /** * Creates a new QueryBuilder. */ protected QueryBuilder createQueryBuilder(String base) { return new QueryBuilder(base); } /** * Executes a daemon query. Extensions should override this method to * provide alternate daemon implementations. */ protected ResultSet executeDaemonQuery(String query) throws SQLException { Statement stmt = connection.createStatement(); daemonize(stmt); return stmt.executeQuery(query); } private void daemonize(Statement stmt) { FarragoJdbcEngineStatement farragoStmt = (FarragoJdbcEngineStatement) stmt; farragoStmt.stmtContext.daemonize(); } // implement DatabaseMetaData public ResultSet getSchemas() throws SQLException { return executeDaemonQuery( "select * from sys_boot.jdbc_metadata.schemas_view " + "order by table_schem,table_catalog"); } // implement DatabaseMetaData public ResultSet getCatalogs() throws SQLException { return executeDaemonQuery( "select * from sys_boot.jdbc_metadata.catalogs_view " + "order by table_cat"); } // implement DatabaseMetaData public ResultSet getTableTypes() throws SQLException { return executeDaemonQuery( "select * from sys_boot.jdbc_metadata.table_types_view " + "order by table_type"); } // implement DatabaseMetaData public ResultSet getColumns( String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.columns_view"); queryBuilder.addExact("table_cat", catalog); queryBuilder.addPattern("table_schem", schemaPattern); queryBuilder.addPattern("table_name", tableNamePattern); queryBuilder.addPattern("column_name", columnNamePattern); queryBuilder.addOrderBy( "table_schem,table_name,ordinal_position,table_cat"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getColumnPrivileges( String catalog, String schema, String table, String columnNamePattern) throws SQLException { throw new UnsupportedOperationException("getColumnPrivileges"); } // implement DatabaseMetaData public ResultSet getTablePrivileges( String catalog, String schemaPattern, String tableNamePattern) throws SQLException { throw new UnsupportedOperationException("getTablePrivileges"); } // implement DatabaseMetaData public ResultSet getBestRowIdentifier( String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { throw new UnsupportedOperationException("getBestRowIdentifier"); } // implement DatabaseMetaData public ResultSet getVersionColumns( String catalog, String schema, String table) throws SQLException { throw new UnsupportedOperationException("getVersionColumns"); } // implement DatabaseMetaData public ResultSet getPrimaryKeys( String catalog, String schema, String table) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.primary_keys_view"); queryBuilder.addExact("table_cat", catalog); queryBuilder.addExact("table_schem", schema); queryBuilder.addExact("table_name", table); queryBuilder.addOrderBy( "column_name, table_cat, table_schem, table_name"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getImportedKeys( String catalog, String schema, String table) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.imported_keys_view"); // For now, ignore all parameters because we always return // empty set. queryBuilder.addOrderBy( "pktable_cat, pktable_schem, pktable_name, key_seq"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getExportedKeys( String catalog, String schema, String table) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.exported_keys_view"); // For now, ignore all parameters because we always return // empty set. queryBuilder.addOrderBy( "fktable_cat, fktable_schem, fktable_name, key_seq"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getCrossReference( String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.cross_reference_view"); // For now, ignore all parameters because we always return // empty set. queryBuilder.addOrderBy( "fktable_cat, fktable_schem, fktable_name, key_seq"); return queryBuilder.execute(); } // implement DatabaseMetaData public ResultSet getTypeInfo() throws SQLException { return executeDaemonQuery( "select * from sys_boot.jdbc_metadata.type_info_view " + "order by data_type"); } // implement DatabaseMetaData public ResultSet getIndexInfo( String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.index_info_view"); queryBuilder.addExact("table_cat", catalog); queryBuilder.addExact("table_schem", schema); queryBuilder.addExact("table_name", table); if (unique) { queryBuilder.addExact( "non_unique", false); } // TODO jvs 22-Oct-2005: do something with parameter "approximate" // as part of implementing stats queryBuilder.addOrderBy( "non_unique, type, index_name, ordinal_position"); return queryBuilder.execute(); } // implement DatabaseMetaData public boolean supportsResultSetType(int type) throws SQLException { return type == ResultSet.TYPE_FORWARD_ONLY; } // implement DatabaseMetaData public boolean supportsResultSetConcurrency( int type, int concurrency) throws SQLException { return (type == ResultSet.TYPE_FORWARD_ONLY) && (concurrency == ResultSet.CONCUR_READ_ONLY); } // implement DatabaseMetaData public boolean ownUpdatesAreVisible(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean ownDeletesAreVisible(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean ownInsertsAreVisible(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean othersUpdatesAreVisible(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean othersDeletesAreVisible(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean othersInsertsAreVisible(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean updatesAreDetected(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean deletesAreDetected(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean insertsAreDetected(int type) throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsBatchUpdates() throws SQLException { return false; } // implement DatabaseMetaData public ResultSet getUDTs( String catalog, String schemaPattern, String typeNamePattern, int [] types) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.udts_view"); queryBuilder.addExact("type_cat", catalog); queryBuilder.addPattern("type_schem", schemaPattern); queryBuilder.addPattern("type_name", typeNamePattern); queryBuilder.addOrderBy("data_type,type_schem,type_name,type_cat"); // TODO: re-enable once IN is working /* queryBuilder.addInList("data_type",types); */ if ((types != null) && (types.length == 1)) { queryBuilder.addExact( "data_type", types[0]); } return queryBuilder.execute(); } // implement DatabaseMetaData public Connection getConnection() throws SQLException { return connection; } // implement DatabaseMetaData public boolean supportsSavepoints() throws SQLException { return true; } // implement DatabaseMetaData public boolean supportsNamedParameters() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsMultipleOpenResults() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsGetGeneratedKeys() throws SQLException { return false; } // implement DatabaseMetaData public ResultSet getSuperTypes( String catalog, String schemaPattern, String typeNamePattern) throws SQLException { // For now, ignore all parameters because we always return // empty set. return executeDaemonQuery( "select * from sys_boot.jdbc_metadata.super_types_view"); } // implement DatabaseMetaData public ResultSet getSuperTables( String catalog, String schemaPattern, String tableNamePattern) throws SQLException { // For now, ignore all parameters because we always return // empty set. return executeDaemonQuery( "select * from sys_boot.jdbc_metadata.super_tables_view"); } // implement DatabaseMetaData public ResultSet getAttributes( String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { QueryBuilder queryBuilder = createQueryBuilder( "select * from sys_boot.jdbc_metadata.attributes_view"); queryBuilder.addExact("type_cat", catalog); queryBuilder.addPattern("type_schem", schemaPattern); queryBuilder.addPattern("type_name", typeNamePattern); queryBuilder.addPattern("attr_name", attributeNamePattern); queryBuilder.addOrderBy( "type_schem,type_name,ordinal_position,type_cat"); return queryBuilder.execute(); } // implement DatabaseMetaData public boolean supportsResultSetHoldability(int holdability) throws SQLException { return holdability == getResultSetHoldability(); } // implement DatabaseMetaData public int getResultSetHoldability() throws SQLException { return ResultSet.CLOSE_CURSORS_AT_COMMIT; } // implement DatabaseMetaData public int getSQLStateType() throws SQLException { // TODO return sqlStateXOpen; } // implement DatabaseMetaData public boolean locatorsUpdateCopy() throws SQLException { return false; } // implement DatabaseMetaData public boolean supportsStatementPooling() throws SQLException { return false; } // // begin JDBC 4 methods // // implement DatabaseMetaData public ResultSet getFunctions( String catalog, String schemaPattern, String functionNamePattern) throws SQLException { throw new UnsupportedOperationException("getFunctions"); } // implement DatabaseMetaData public ResultSet getFunctionColumns( String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException { throw new UnsupportedOperationException("getFunctionColumns"); } // implement DatabaseMetaData public ResultSet getClientInfoProperties() throws SQLException { throw new UnsupportedOperationException("getClientInfoProperties"); } // implement DatabaseMetaData public boolean autoCommitFailureClosesAllResultSets() throws SQLException { throw new UnsupportedOperationException( "autoCommitFailureClosesAllResultSets"); } // implement DatabaseMetaData public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { throw new UnsupportedOperationException( "supportsStoredFunctionsUsingCallSyntax"); } // implement DatabaseMetaData public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { throw new UnsupportedOperationException("getSchemas"); } // implement DatabaseMetaData public RowIdLifetime getRowIdLifetime() throws SQLException { throw new UnsupportedOperationException("getRowIdLifetime"); } //~ Inner Classes ---------------------------------------------------------- // // end JDBC 4 methods // /** * Helper class for building up queries used by metadata calls. */ protected class QueryBuilder { protected StringBuilder sql; protected List values; private boolean whereAdded; protected QueryBuilder(String base) { sql = new StringBuilder(base); values = new ArrayList(); } void addConjunction() { if (!whereAdded) { sql.append(" WHERE "); } else { sql.append(" AND "); } whereAdded = true; } void addPattern( String colName, String value) { if (value == null) { return; } if (value.equals("%")) { addConjunction(); sql.append(colName); sql.append(" IS NOT NULL"); return; } if (!repos.isFennelEnabled()) { // Without Fennel, we don't yet support LIKE, so just // try our best by ignoring the pattern and treating it // as an exact match. addExact(colName, value); return; } if ((value.indexOf('%') == -1) && (value.indexOf('_') == -1)) { // They didn't supply a pattern anyway. addExact(colName, value); return; } addConjunction(); sql.append(colName); sql.append(" like ? escape '\\'"); values.add(value); } void addExact( String colName, Serializable value) { if (value == null) { return; } addConjunction(); sql.append(colName); sql.append(" = ?"); values.add(value); } void addInList( String colName, String [] valueList) { if (valueList == null) { return; } addConjunction(); sql.append(colName); sql.append(" in ("); for (int i = 0; i < valueList.length; ++i) { if (i > 0) { sql.append(","); } // REVIEW: automatically uppercase? sql.append("'"); sql.append(valueList[i]); sql.append("'"); } sql.append(")"); } void addOrderBy(String colList) { sql.append(" ORDER BY "); sql.append(colList); } protected ResultSet execute() throws SQLException { PreparedStatement stmt = connection.prepareStatement(sql.toString()); daemonize(stmt); for (int i = 0; i < values.size(); ++i) { stmt.setObject( i + 1, values.get(i)); } return stmt.executeQuery(); } } } // End FarragoJdbcEngineDatabaseMetaData.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineDriver.java0000444000175000017500000000316111173714170030044 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineDriver.java#20 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.engine; /** * FarragoJdbcEngineDriver implements the Farrago engine/server side of the * {@link java.sql.Driver} interface. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/engine/FarragoJdbcEngineDriver.java#20 $ */ public class FarragoJdbcEngineDriver extends FarragoUnregisteredJdbcEngineDriver { //~ Static fields/initializers --------------------------------------------- static { new FarragoJdbcEngineDriver().register(); } } // End FarragoJdbcEngineDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/FarragoAbstractJdbcDriver.java0000444000175000017500000002224111173714170027135 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoAbstractJdbcDriver.java#22 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc; import java.sql.*; import java.util.*; import net.sf.farrago.release.*; import org.eigenbase.util14.*; /** * FarragoAbstractJdbcDriver is an abstract base for the client and engine sides * of the Farrago JDBC driver. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoAbstractJdbcDriver.java#22 $ */ public abstract class FarragoAbstractJdbcDriver implements Driver { //~ Methods ---------------------------------------------------------------- // implement Driver public boolean jdbcCompliant() { // TODO: true once we pass compliance tests and SQL92 entry level return false; } /** * @return the prefix for JDBC URL's understood by this driver */ public abstract String getUrlPrefix(); /** * @return the base JDBC URL for this driver; subclassing drivers can * override this to customize the URL scheme */ public String getBaseUrl() { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.jdbcUrlBase.get(); } /** * @return the JDBC URL interpreted by the engine driver as a connection * from an RMI client; subclassing drivers can override this to customize * the URL scheme */ public String getClientUrl() { // NOTE jvs 27-March-2004: At the moment, the driver interprets // embedded and client URL's as the same. However, we distinguish // the actual URL's since in the future we may want to // react to them differently. return getBaseUrl() + "client_rmi"; } // implement Driver public int getMajorVersion() { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.jdbcDriverVersionMajor.get(); } // implement Driver public int getMinorVersion() { FarragoReleaseProperties props = FarragoReleaseProperties.instance(); return props.jdbcDriverVersionMinor.get(); } // implement Driver public DriverPropertyInfo [] getPropertyInfo( String url, Properties info) throws SQLException { // TODO return new DriverPropertyInfo[0]; } // implement Driver public boolean acceptsURL(String url) throws SQLException { if (url == null) { return false; } if (!url.startsWith(getUrlPrefix())) { return false; } // Make sure we don't accidentally steal a URL intended for // an RMI driver which accepts a longer prefix. String suffix = url.substring(getUrlPrefix().length()); if (suffix.startsWith("rmi:")) { return false; } return true; } /** * Indicates whether driver accepts URLs with host:port specification. * Returns false by default. Subclassing drivers should * override and return true to enable FarragoTestCase to create URLs with * host:port specifications. * * @return false */ public boolean acceptsUrlWithHostPort() { return false; } public void register() { try { DriverManager.registerDriver(this); } catch (SQLException e) { System.out.println( "Error occurred while registering JDBC driver " + this + ": " + e.toString()); } } /** * Returns new Properties object with all input properties and default * connection properties. Input properties take precedence over default * properties. * * @param info input properties, copied but unchanged * * @return new Properties object, never null * * @see #getDefaultConnectionProps */ public Properties applyDefaultConnectionProps(final Properties info) { // copy default properties to new properties Properties props = copyProperties( getDefaultConnectionProps(), null); // copy input properties to new properties return copyProperties(info, props); } /** * Returns default connection properties. * * @return new Properties object, never null * * @see #applyDefaultConnectionProps */ public Properties getDefaultConnectionProps() { Properties props = new Properties(); // default user id is Java user name String userName = System.getProperty("user.name"); if (userName != null) { props.setProperty("clientUserName", userName); } //REVIEW: add default for sessionName? /** * To set process ID, use a shell script to launch the JVM and use "exec" * to replace the shell process with the JVM. This allows you to pass the * shell's PID to the JVM: * #!/bin/bash * exec java -Dprocess.id=$$ the.class.name * (Without exec, $$ is the bash process's PID.) */ String processId = System.getProperty("process.id"); if (processId != null) { props.setProperty("clientProcessId", processId); } return props; } /** * Returns destination Properties object after copying source properties * into it. Any existing destination property with the same name as a source * property is replaced by the source property. A new destination Properties * object is created if the input argument is null. Note: * Properties object is treated like a Hashtable and all key-value pairs are * copied, regardless of whether the keys or values are Strings. Chained * Properties objects are OK, but there is no API for accessing non-String * values from chained Properties object. So only String values can be * copied from chained Properties. * * @param src source properties, must not be null * @param dest destination properties, may be null * * @return merged properties */ private Properties copyProperties(final Properties src, Properties dest) { if (dest == null) { dest = new Properties(); } // get all keys, including from chained Properties objects Enumeration enumer = src.propertyNames(); while (enumer.hasMoreElements()) { // use Hashtable API so can copy non-String keys and values Object key = enumer.nextElement(); Object val = src.get(key); // but Hashtable.get() does not search chained Properties, // so keys that reference chained properties return null if (val == null) { if (key instanceof String) { val = src.getProperty((String) key); } if (val == null) { // item in chained Properties object with // non-String key or value is not accessible continue; } } dest.put(key, val); } return dest; } /** * Parses params from connection string into {@link Properties} object, * returning the stripped URI. * * @param connectionURI connection string with optional params * @param info Properties object; pass null to just get the * stripped URI * * @return connection URI stripped of params; parameters parsed into * info if not null. * * @throws SQLException */ public String parseConnectionParams(String connectionURI, Properties info) throws SQLException { if (connectionURI == null) { return null; } // separate the URI and connection params at the first semicolon int i = connectionURI.indexOf(';'); if (i < 0) { return connectionURI; } String uri = connectionURI.substring(0, i); String params = connectionURI.substring(i + 1); ConnectStringParser.parse(params, info); return uri; } } // End FarragoAbstractJdbcDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/package.html0000444000175000017500000000134011173714170023544 0ustar drazzibdrazzib Package net.sf.farrago.jdbc Provides common classes shared by both the client and engine sides of the Farrago JDBC driver.

NOTE jvs 2-Oct-2005: This package gets included in client-side code, so it must be source-compatible with JDK 1.4.

 

Revision $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/package.html#10 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/0000755000175000017500000000000011173714170022367 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcParamDefFactory.java0000444000175000017500000001004111173714170030320 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcParamDefFactory.java#13 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.sql.*; /** * Factory for {@link FarragoJdbcParamDef} objects. * *

Refactored from FarragoJdbcEngineParamDefFactory. * *

This class is JDK 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcParamDefFactory.java#13 $ */ public class FarragoJdbcParamDefFactory { //~ Static fields/initializers --------------------------------------------- public static final FarragoJdbcParamDefFactory instance = new FarragoJdbcParamDefFactory(); //~ Constructors ----------------------------------------------------------- /** * Creates a FarragoJdbcParamDefFactory. */ private FarragoJdbcParamDefFactory() { } //~ Methods ---------------------------------------------------------------- public FarragoJdbcParamDef newParamDef( String paramName, FarragoParamFieldMetaData paramMetaData, boolean useFennelTuple) { if (useFennelTuple) { return newFennelTupleParamDef(paramName, paramMetaData); } else { return newParamDef(paramName, paramMetaData); } } private static FarragoJdbcParamDef newFennelTupleParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { FarragoJdbcParamDef paramDef = newParamDef(paramName, paramMetaData); return new FarragoJdbcFennelTupleParamDef( paramName, paramMetaData, paramDef); } private static FarragoJdbcParamDef newParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { switch (paramMetaData.type) { case Types.BIT: case Types.BOOLEAN: return new FarragoJdbcBooleanParamDef(paramName, paramMetaData); case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: return new FarragoJdbcIntParamDef(paramName, paramMetaData); case Types.REAL: case Types.FLOAT: case Types.DOUBLE: return new FarragoJdbcApproxParamDef(paramName, paramMetaData); case Types.DECIMAL: case Types.NUMERIC: return new FarragoJdbcDecimalParamDef(paramName, paramMetaData); case Types.CHAR: case Types.VARCHAR: return new FarragoJdbcStringParamDef(paramName, paramMetaData); case Types.BINARY: case Types.VARBINARY: return new FarragoJdbcBinaryParamDef(paramName, paramMetaData); case Types.DATE: return new FarragoJdbcDateParamDef(paramName, paramMetaData); case Types.TIMESTAMP: return new FarragoJdbcTimestampParamDef(paramName, paramMetaData); case Types.TIME: return new FarragoJdbcTimeParamDef(paramName, paramMetaData); default: return new FarragoJdbcParamDef(paramName, paramMetaData); } } } // End FarragoJdbcParamDefFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcTimestampParamDef.java0000444000175000017500000000744111173714170030666 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcTimestampParamDef.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.sql.Timestamp; import java.util.Calendar; import org.eigenbase.util14.*; /** * FarragoJdbcEngineTimestampParamDef defines a Timestamp parameter. * *

This class is JDK 1.4 compatible. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcTimestampParamDef.java#11 $ */ class FarragoJdbcTimestampParamDef extends FarragoJdbcParamDef { //~ Constructors ----------------------------------------------------------- /** * Creates a FarragoJdbcEngineTimestampParamDef. * * @param paramName Name * @param paramMetaData Meta data */ FarragoJdbcTimestampParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { return scrubValue( x, Calendar.getInstance()); } // implement FarragoSessionStmtParamDef // Converts parameters from timezone in calendar into gmt time. public Object scrubValue(Object x, Calendar cal) { if (x == null) { checkNullable(); return x; } if (x instanceof String) { String s = ((String) x).trim(); ZonelessTimestamp ts = ZonelessTimestamp.parse(s); if (ts == null) { throw newInvalidFormat(x); } return ts; } // Of the subtypes of java.util.Date, // only java.sql.Date and java.sql.Timestamp are OK. // java.sql.Time is not okay (no date information). if ((x instanceof Timestamp) || (x instanceof java.sql.Date)) { java.util.Date timestamp = (java.util.Date) x; ZonelessTimestamp zt = new ZonelessTimestamp(); zt.setZonedTime(timestamp.getTime(), DateTimeUtil.getTimeZone(cal)); return zt; } // ZonelessDatetime is not required by JDBC, but we allow it because // it is a convenient format to serialize values over RMI. // We disallow ZonelessTime for the same reasons we disallow // java.sql.Time above. if (x instanceof ZonelessTimestamp) { // Do not shift time - value has already been shifted. return x; } else if (x instanceof ZonelessDate) { long time = ((ZonelessDatetime) x).getTime(); ZonelessTimestamp zt = new ZonelessTimestamp(); zt.setZonelessTime(time); return zt; } throw newInvalidType(x); } } // End FarragoJdbcTimestampParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcBinaryParamDef.java0000444000175000017500000000471711173714170030152 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcBinaryParamDef.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import org.eigenbase.util14.*; /** * FarragoJdbcEngineBinaryParamDef defines a binary parameter. Only accepts * byte-array values. This class is JDK 1.4 compatible. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcBinaryParamDef.java#7 $ */ class FarragoJdbcBinaryParamDef extends FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- private final int maxByteCount; //~ Constructors ----------------------------------------------------------- public FarragoJdbcBinaryParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); maxByteCount = paramMetaData.precision; } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { if (x == null) { checkNullable(); return x; } if (!(x instanceof byte [])) { throw newInvalidType(x); } final byte [] bytes = (byte []) x; if (bytes.length > maxByteCount) { throw newValueTooLong( ConversionUtil.toStringFromByteArray(bytes, 16)); } return bytes; } } // End FarragoJdbcBinaryParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcDecimalParamDef.java0000444000175000017500000000625311173714170030261 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcDecimalParamDef.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.math.*; import org.eigenbase.util14.*; /** * FarragoJdbcEngineDecimalParamDef defines a Decimal parameter. This class is * JDK 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcDecimalParamDef.java#7 $ */ class FarragoJdbcDecimalParamDef extends FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- final BigInteger maxUnscaled; final BigInteger minUnscaled; //~ Constructors ----------------------------------------------------------- FarragoJdbcDecimalParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); maxUnscaled = NumberUtil.getMaxUnscaled(paramMetaData.precision); minUnscaled = NumberUtil.getMinUnscaled(paramMetaData.precision); } //~ Methods ---------------------------------------------------------------- private BigDecimal getBigDecimal(Object value, int scale) { BigDecimal bd; if (value == null) { checkNullable(); return null; } else if (value instanceof Number) { bd = NumberUtil.toBigDecimal((Number) value); } else if (value instanceof Boolean) { bd = new BigDecimal(((Boolean) value).booleanValue() ? 1 : 0); } else if (value instanceof String) { try { bd = new BigDecimal(value.toString().trim()); } catch (NumberFormatException ex) { throw newInvalidFormat(value); } } else { throw newInvalidType(value); } bd = NumberUtil.rescaleBigDecimal(bd, scale); return bd; } // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { BigDecimal n = getBigDecimal(x, paramMetaData.scale); if (n != null) { BigInteger usv = n.unscaledValue(); checkRange(usv, minUnscaled, maxUnscaled); } return n; } } // End FarragoJdbcDecimalParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/package.html0000444000175000017500000000132011173714170024642 0ustar drazzibdrazzib Package net.sf.farrago.jdbc.param Provide classes for implementing dynamic parameters for the Farrago JDBC driver.

NOTE angel 17-March-2006: This package gets included in client-side code, so it must be source-compatible with JDK 1.4.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/package.html#4 $
Copyright Copyright (C) 2006-2009 The Eigenbase Project
Copyright (C) 2006-2009 SQLstream, Inc.
Copyright (C) 2006-2009 LucidEra, Inc.
Author Angel Chang
eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcIntParamDef.java0000444000175000017500000001026511173714170027453 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcIntParamDef.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2006-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.math.*; import java.sql.*; import org.eigenbase.util14.*; /** * FarragoJdbcEngineIntParamDef defines a integer parameter. This class is JDK * 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcIntParamDef.java#11 $ */ class FarragoJdbcIntParamDef extends FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- final long min; final long max; //~ Constructors ----------------------------------------------------------- FarragoJdbcIntParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); switch (paramMetaData.type) { case Types.TINYINT: min = Byte.MIN_VALUE; max = Byte.MAX_VALUE; break; case Types.SMALLINT: min = Short.MIN_VALUE; max = Short.MAX_VALUE; break; case Types.INTEGER: min = Integer.MIN_VALUE; max = Integer.MAX_VALUE; break; case Types.BIGINT: min = Long.MIN_VALUE; max = Long.MAX_VALUE; break; default: min = 0; max = 0; assert (false) : "Integral paramMetaData expected"; } } //~ Methods ---------------------------------------------------------------- private long getLong(Object value) { if (value instanceof Long) { // Case "value instanceof Number" below is not sufficient for Long: // conversion via double loses precision for values > 2^48. OK for // other types, including int and float. return ((Long) value).longValue(); } else if (value instanceof Number) { Number n = (Number) value; return NumberUtil.round(n.doubleValue()); } else if (value instanceof Boolean) { return (((Boolean) value).booleanValue() ? 1 : 0); } else if (value instanceof String) { try { BigDecimal bd = new BigDecimal(value.toString().trim()); return getLong(bd); } catch (NumberFormatException ex) { throw newInvalidFormat(value); } } else { throw newInvalidType(value); } } // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { if (x == null) { checkNullable(); return null; } else { long n = getLong(x); checkRange(n, min, max); switch (paramMetaData.type) { case Types.TINYINT: return new Byte((byte) n); case Types.SMALLINT: return new Short((short) n); case Types.INTEGER: return new Integer((int) n); case Types.BIGINT: return new Long(n); default: throw new AssertionError("bad type " + paramMetaData.type); } } } } // End FarragoJdbcIntParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcBooleanParamDef.java0000444000175000017500000000553111173714170030300 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcBooleanParamDef.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2006-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import org.eigenbase.util14.*; /** * FarragoJdbcEngineBooleanParamDef defines a boolean parameter. This class is * JDK 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcBooleanParamDef.java#8 $ */ class FarragoJdbcBooleanParamDef extends FarragoJdbcParamDef { //~ Constructors ----------------------------------------------------------- FarragoJdbcBooleanParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { if (x == null) { checkNullable(); return null; } else { if (x instanceof Boolean) { return x; } else if (x instanceof Number) { Number n = (Number) x; return Boolean.valueOf(n.longValue() != 0); } else if (x instanceof String) { try { return ConversionUtil.toBoolean((String) x); } catch (Exception e) { // Convert string to number, return false if zero try { String str = ((String) x).trim(); double d = Double.parseDouble(str); return Boolean.valueOf(d != 0); } catch (NumberFormatException ex) { throw newInvalidFormat(x); } } } else { throw newInvalidType(x); } } } } // End FarragoJdbcBooleanParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoParamFieldMetaData.java0000444000175000017500000000631211173714170030141 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoParamFieldMetaData.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2006-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.io.*; import java.sql.*; /** * This defines the per parameter field metadata required by the client-side * driver to implement the JDBC ParameterMetaData API. This class is JDK 1.4 * compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoParamFieldMetaData.java#8 $ * @see net.sf.farrago.jdbc.engine.FarragoParamFieldMetaDataFactory */ public class FarragoParamFieldMetaData implements Serializable { //~ Static fields/initializers --------------------------------------------- /** * SerialVersionUID created with JDK 1.5 serialver tool. */ private static final long serialVersionUID = 5042520840301805755L; //~ Instance fields -------------------------------------------------------- /** * SQL paramMetaData of this field. */ public int type; /** * SQL className. */ public String className; /** * SQL typename of this field. */ public String typeName; /** * precision of this field. */ public int precision; /** * scale of this field. */ public int scale; /** * indicates whether this parameter field is nullable. One of {{@link * java.sql.ParameterMetaData#parameterNoNulls}, {@link * java.sql.ParameterMetaData#parameterNullable}, {@link * java.sql.ParameterMetaData#parameterNullableUnknown}}. */ public int nullable = ParameterMetaData.parameterNullableUnknown; /** * indicates whether this field is signed. */ public boolean signed; /** * indicate the parameter mode. One of {{@link * java.sql.ParameterMetaData#parameterModeUnknown}, {@link * java.sql.ParameterMetaData#parameterModeIn}, {@link * java.sql.ParameterMetaData#parameterModeOut}, {@link * java.sql.ParameterMetaData#parameterModeInOut}. */ public int mode = ParameterMetaData.parameterModeUnknown; /** * String describing the parameter type Usually of the form: typeName * (precision, scale) */ public String paramTypeStr; } // End FarragoParamFieldMetaData.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcFennelTupleParamDef.java0000444000175000017500000005045411173714170031146 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcFennelTupleParamDef.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2006-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.math.*; import java.sql.*; import java.util.Calendar; import net.sf.farrago.fennel.tuple.*; import org.eigenbase.util14.*; /** * FarragoJdbcFennelTupleParamDef represents a parameter associated with a * FennelTupleDatum. It handles data converstions to the target type. This class * is JDK 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcFennelTupleParamDef.java#11 $ * @since March 3, 2006 */ public class FarragoJdbcFennelTupleParamDef extends FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- /* ParamDef (non fennel version) used to override scrubValue */ private FarragoJdbcParamDef defaultParamDef; protected Number min; protected Number max; //~ Constructors ----------------------------------------------------------- public FarragoJdbcFennelTupleParamDef( String paramName, FarragoParamFieldMetaData param, FarragoJdbcParamDef paramDef) { super(paramName, param); defaultParamDef = paramDef; switch (paramMetaData.type) { case Types.TINYINT: min = NumberUtil.MIN_BYTE; max = NumberUtil.MAX_BYTE; break; case Types.SMALLINT: min = NumberUtil.MIN_SHORT; max = NumberUtil.MAX_SHORT; break; case Types.INTEGER: min = NumberUtil.MIN_INTEGER; max = NumberUtil.MAX_INTEGER; break; case Types.BIGINT: min = NumberUtil.MIN_LONG; max = NumberUtil.MAX_LONG; break; case Types.NUMERIC: case Types.DECIMAL: min = NumberUtil.getMinUnscaled(paramMetaData.precision); max = NumberUtil.getMaxUnscaled(paramMetaData.precision); break; case Types.BIT: case Types.BOOLEAN: min = NumberUtil.INTEGER_ZERO; max = NumberUtil.INTEGER_ONE; break; case Types.REAL: min = NumberUtil.MIN_FLOAT; max = NumberUtil.MAX_FLOAT; break; case Types.FLOAT: case Types.DOUBLE: min = NumberUtil.MIN_DOUBLE; max = NumberUtil.MAX_DOUBLE; break; } } //~ Methods ---------------------------------------------------------------- public Object scrubValue(Object obj) { if (defaultParamDef != null) { return defaultParamDef.scrubValue(obj); } else { return super.scrubValue(obj); } } public Object scrubValue(Object obj, Calendar cal) { if (defaultParamDef != null) { return defaultParamDef.scrubValue(obj, cal); } else { return super.scrubValue(obj, cal); } } public void setNull(FennelTupleDatum datum) { checkNullable(); datum.reset(); } public void setBoolean(FennelTupleDatum datum, boolean b) { switch (paramMetaData.type) { case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: datum.setLong(b ? 1 : 0); break; case Types.NUMERIC: case Types.DECIMAL: datum.setLong( b ? NumberUtil.powTen(paramMetaData.scale).longValue() : 0); break; case Types.BIT: case Types.BOOLEAN: datum.setBoolean(b); break; case Types.REAL: datum.setFloat(b ? 1 : 0); break; case Types.FLOAT: case Types.DOUBLE: datum.setDouble(b ? 1 : 0); break; case Types.VARCHAR: case Types.CHAR: setString( paramMetaData.type == Types.CHAR, datum, b ? "true" : "false", Boolean.class); break; default: throw newInvalidType(Boolean.class); } } public void setByte(FennelTupleDatum datum, byte val) { setLong(datum, (long) val, Byte.class); } public void setShort(FennelTupleDatum datum, short val) { setLong(datum, (long) val, Short.class); } public void setInt(FennelTupleDatum datum, int val) { setLong(datum, (long) val, Integer.class); } public void setLong(FennelTupleDatum datum, long val) { setLong(datum, (long) val, Long.class); } private void setLong(FennelTupleDatum datum, long val, Class clazz) { switch (paramMetaData.type) { case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: checkRange( val, min.longValue(), max.longValue()); datum.setLong((long) val); break; case Types.NUMERIC: case Types.DECIMAL: BigDecimal bd = NumberUtil.rescaleBigDecimal( BigDecimal.valueOf(val), paramMetaData.scale); checkRange( bd.unscaledValue(), (BigInteger) min, (BigInteger) max); datum.setLong(bd.unscaledValue().longValue()); break; case Types.BIT: case Types.BOOLEAN: datum.setBoolean(val != 0); break; case Types.REAL: datum.setFloat((float) val); break; case Types.FLOAT: case Types.DOUBLE: datum.setDouble((double) val); break; case Types.VARCHAR: case Types.CHAR: setString( paramMetaData.type == Types.CHAR, datum, Long.toString(val), clazz); break; default: throw newInvalidType(clazz); } } public void setFloat(FennelTupleDatum datum, float val) { setDouble(datum, (double) val, true); } public void setDouble(FennelTupleDatum datum, double val) { setDouble(datum, (double) val, false); } private void setDouble(FennelTupleDatum datum, double val, boolean isFloat) { Class clazz; if (isFloat) { clazz = Float.class; } else { clazz = Double.class; } switch (paramMetaData.type) { case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: long n = NumberUtil.round(val); checkRange( n, min.longValue(), max.longValue()); datum.setLong(n); break; case Types.NUMERIC: case Types.DECIMAL: BigDecimal bd = NumberUtil.rescaleBigDecimal( new BigDecimal(val), paramMetaData.scale); checkRange( bd.unscaledValue(), (BigInteger) min, (BigInteger) max); datum.setLong(bd.unscaledValue().longValue()); break; case Types.BIT: case Types.BOOLEAN: datum.setBoolean(val != 0); break; case Types.REAL: checkRange( val, min.doubleValue(), max.doubleValue()); datum.setFloat((float) val); break; case Types.FLOAT: case Types.DOUBLE: checkRange( val, min.doubleValue(), max.doubleValue()); datum.setDouble((double) val); break; case Types.VARCHAR: case Types.CHAR: if (isFloat) { setString( paramMetaData.type == Types.CHAR, datum, Float.toString((float) val), clazz); } else { setString( paramMetaData.type == Types.CHAR, datum, Double.toString(val), clazz); } break; default: throw newInvalidType(clazz); } } public void setBigDecimal(FennelTupleDatum datum, BigDecimal val) { if (val == null) { setNull(datum); return; } BigDecimal bd; switch (paramMetaData.type) { case Types.TINYINT: bd = NumberUtil.rescaleBigDecimal(val, 0); checkRange( bd.doubleValue(), min.doubleValue(), max.doubleValue()); datum.setByte(bd.byteValue()); break; case Types.SMALLINT: bd = NumberUtil.rescaleBigDecimal(val, 0); checkRange( bd.doubleValue(), min.doubleValue(), max.doubleValue()); datum.setShort(bd.shortValue()); break; case Types.INTEGER: bd = NumberUtil.rescaleBigDecimal(val, 0); checkRange( bd.doubleValue(), min.doubleValue(), max.doubleValue()); datum.setInt(bd.intValue()); break; case Types.BIGINT: bd = NumberUtil.rescaleBigDecimal(val, 0); checkRange( bd.doubleValue(), min.doubleValue(), max.doubleValue()); datum.setLong(bd.longValue()); break; case Types.NUMERIC: case Types.DECIMAL: bd = NumberUtil.rescaleBigDecimal(val, paramMetaData.scale); checkRange( bd.unscaledValue(), (BigInteger) min, (BigInteger) max); datum.setLong(bd.unscaledValue().longValue()); break; case Types.BIT: case Types.BOOLEAN: datum.setBoolean(!val.equals(BigDecimal.valueOf(0))); break; case Types.REAL: checkRange( val.doubleValue(), min.doubleValue(), max.doubleValue()); datum.setFloat(val.floatValue()); break; case Types.FLOAT: case Types.DOUBLE: checkRange( val.doubleValue(), min.doubleValue(), max.doubleValue()); datum.setDouble(val.doubleValue()); break; case Types.VARCHAR: case Types.CHAR: setString( paramMetaData.type == Types.CHAR, datum, val.toString(), BigDecimal.class); break; default: throw newInvalidType(BigDecimal.class); } } private void setString( boolean pad, FennelTupleDatum datum, String val, Class clazz) { if (datum.getCapacity() >= val.length()) { if (pad && (datum.getCapacity() > val.length())) { // Use StringBuffer instead of StringBuilder for JDK 1.4 // compatibility StringBuffer buf = new StringBuffer(datum.getCapacity()); buf.append(val); for (int i = val.length(); i < datum.getCapacity(); i++) { buf.append(' '); } val = buf.toString(); } datum.setString(val); } else { throw newValueTooLong(val); } } public void setString(FennelTupleDatum datum, String val) { if (val == null) { setNull(datum); return; } switch (paramMetaData.type) { case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: case Types.BIGINT: try { long n = Long.parseLong(val.trim()); checkRange( n, min.longValue(), max.longValue()); datum.setLong(n); } catch (NumberFormatException e) { throw newInvalidFormat(val); } break; case Types.NUMERIC: case Types.DECIMAL: try { BigDecimal bd = NumberUtil.rescaleBigDecimal( new BigDecimal(val.trim()), paramMetaData.scale); checkRange( bd.unscaledValue(), (BigInteger) min, (BigInteger) max); datum.setLong(bd.unscaledValue().longValue()); } catch (Throwable ex) { throw newInvalidFormat(val); } break; case Types.BIT: case Types.BOOLEAN: try { Boolean boolVal = ConversionUtil.toBoolean(val.trim()); if (boolVal == null) { setNull(datum); } else { datum.setBoolean(boolVal.booleanValue()); } } catch (Throwable ex) { // Convert string to number, return false if zero try { double d = Double.parseDouble(val.trim()); datum.setBoolean(d != 0); } catch (NumberFormatException e) { throw newInvalidFormat(val); } } break; case Types.REAL: try { float n = Float.parseFloat(val.trim()); checkRange( n, min.doubleValue(), max.doubleValue()); datum.setFloat(n); } catch (NumberFormatException e) { throw newInvalidFormat(val); } break; case Types.FLOAT: case Types.DOUBLE: try { double n = Double.parseDouble(val.trim()); checkRange( n, min.doubleValue(), max.doubleValue()); datum.setDouble(n); } catch (NumberFormatException e) { throw newInvalidFormat(val); } break; case Types.VARCHAR: case Types.CHAR: setString( paramMetaData.type == Types.CHAR, datum, val, val.getClass()); break; case Types.DATE: try { datum.setLong(Date.valueOf(val.trim()).getTime()); } catch (IllegalArgumentException e) { throw newInvalidFormat(val); } break; case Types.TIME: try { datum.setLong(Time.valueOf(val.trim()).getTime()); } catch (IllegalArgumentException e) { throw newInvalidFormat(val); } break; case Types.TIMESTAMP: try { datum.setLong(Timestamp.valueOf(val.trim()).getTime()); } catch (IllegalArgumentException e) { throw newInvalidFormat(val); } break; default: throw newInvalidType(val); } } public void setDate(FennelTupleDatum datum, ZonelessDate val) { if (val == null) { setNull(datum); return; } switch (paramMetaData.type) { case Types.CHAR: case Types.VARCHAR: setString( paramMetaData.type == Types.CHAR, datum, val.toString(), val.getClass()); break; case Types.DATE: case Types.TIMESTAMP: datum.setLong(val.getTime()); break; default: throw newInvalidType(val); } } public void setTime(FennelTupleDatum datum, ZonelessTime val) { if (val == null) { setNull(datum); return; } switch (paramMetaData.type) { case Types.CHAR: case Types.VARCHAR: setString( paramMetaData.type == Types.CHAR, datum, val.toString(), val.getClass()); break; case Types.TIME: datum.setLong(val.getTime()); break; default: throw newInvalidType(val); } } public void setTimestamp(FennelTupleDatum datum, ZonelessTimestamp val) { if (val == null) { setNull(datum); return; } switch (paramMetaData.type) { case Types.CHAR: case Types.VARCHAR: setString( paramMetaData.type == Types.CHAR, datum, val.toString(), val.getClass()); break; case Types.TIME: case Types.DATE: case Types.TIMESTAMP: datum.setLong(val.getTime()); break; default: throw newInvalidType(val); } } public void setBytes(FennelTupleDatum datum, byte [] val) { if (val == null) { setNull(datum); return; } switch (paramMetaData.type) { case Types.BINARY: case Types.VARBINARY: if (val.length > datum.getCapacity()) { throw newValueTooLong(val); } datum.setBytes(val); break; default: throw newInvalidType(val); } } public void setObject(FennelTupleDatum datum, Object val) { if (val == null) { setNull(datum); return; } if (val instanceof String) { setString(datum, (String) val); } else if (val instanceof Boolean) { setBoolean( datum, ((Boolean) val).booleanValue()); } else if (val instanceof BigDecimal) { setBigDecimal(datum, (BigDecimal) val); } else if (val instanceof Number) { Number n = (Number) val; if (val instanceof Float) { setDouble( datum, n.doubleValue(), false); } else if (val instanceof Double) { setDouble( datum, n.doubleValue(), true); } else if ( (val instanceof Byte) || (val instanceof Short) || (val instanceof Integer) || (val instanceof Long)) { setLong( datum, n.longValue(), val.getClass()); } else { setBigDecimal( datum, NumberUtil.toBigDecimal(n)); } } else if (val instanceof ZonelessTime) { setTime(datum, (ZonelessTime) val); } else if (val instanceof ZonelessDate) { setDate(datum, (ZonelessDate) val); } else if (val instanceof ZonelessTimestamp) { setTimestamp(datum, (ZonelessTimestamp) val); } else if (val instanceof byte []) { setBytes(datum, (byte []) val); } else { throw newInvalidType(val); } } } // End FarragoJdbcFennelTupleParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcStringParamDef.java0000444000175000017500000000555111173714170030171 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcStringParamDef.java#9 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; /** * FarragoJdbcEngineStringParamDef defines a string parameter. Values which are * not strings are converted into strings. Strings are not padded, even for CHAR * columns. This class is JDK 1.4 compatible. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcStringParamDef.java#9 $ */ class FarragoJdbcStringParamDef extends FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- private final int maxCharCount; //~ Constructors ----------------------------------------------------------- public FarragoJdbcStringParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); maxCharCount = paramMetaData.precision; } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { if (x == null) { checkNullable(); return x; } if (x instanceof String) { if (((String) x).length() > maxCharCount) { // TODO: SQLWarning return ((String) x).substring(0, maxCharCount); } return x; } if (x instanceof byte []) { // Don't allow binary to placed in string throw newInvalidType(x); } // REVIEW jvs 7-Oct-2004: the default toString() implementation for // Float/Double/Date/Time/Timestamp/byte[] may not be correct here. final String s = x.toString(); if (s.length() > maxCharCount) { throw newValueTooLong(s); } return s; } } // End FarragoJdbcStringParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcDateParamDef.java0000444000175000017500000000677711173714170027613 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcDateParamDef.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.sql.Timestamp; import java.util.Calendar; import org.eigenbase.util14.*; /** * FarragoJdbcEngineDateParamDef defines a date parameter. * *

This class is JDK 1.4 compatible. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcDateParamDef.java#10 $ */ class FarragoJdbcDateParamDef extends FarragoJdbcParamDef { //~ Constructors ----------------------------------------------------------- public FarragoJdbcDateParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { return scrubValue( x, Calendar.getInstance()); } // implement FarragoSessionStmtParamDef // Converts parameters from timezone in calendar into gmt time. public Object scrubValue(Object x, Calendar cal) { if (x == null) { checkNullable(); return null; } if (x instanceof String) { String s = ((String) x).trim(); ZonelessDate zd = ZonelessDate.parse(s); if (zd == null) { throw newInvalidFormat(x); } return zd; } // Of the subtypes of java.util.Date, // only java.sql.Date and java.sql.Timestamp are OK. // java.sql.Time is not okay (no date information). if ((x instanceof Timestamp) || (x instanceof java.sql.Date)) { java.util.Date d = (java.util.Date) x; ZonelessDate zd = new ZonelessDate(); zd.setZonedTime(d.getTime(), DateTimeUtil.getTimeZone(cal)); return zd; } // ZonelessDatetime is not required by JDBC, but we allow it because // it is a convenient format to serialize values over RMI. // We disallow ZonelessTime for the same reasons we disallow // java.sql.Time above. if ((x instanceof ZonelessTimestamp) || (x instanceof ZonelessDate)) { ZonelessDate zd = new ZonelessDate(); long time = ((ZonelessDatetime) x).getTime(); zd.setZonedTime(time, DateTimeUtil.getTimeZone(cal)); return zd; } throw newInvalidType(x); } } // End FarragoJdbcDateParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcParamDef.java0000444000175000017500000001472611173714170027006 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcParamDef.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.math.*; import java.sql.*; import java.util.*; import org.eigenbase.util.*; /** * Handles data conversion for a dynamic parameter (refactored from * FarragoJdbcEngineParamDef) Enforces constraints on parameters. The * constraints are: * *

    *
  1. Ensures that null values cannot be inserted into not-null columns. *
  2. Ensures that value is the right paramMetaData. *
  3. Ensures that the value is within range. For example, you can't insert a * 10001 into a DECIMAL(5) column. *
* *

TODO: Actually enfore these constraints. This class is JDK 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcParamDef.java#10 $ */ public class FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- final FarragoParamFieldMetaData paramMetaData; final String paramName; //~ Constructors ----------------------------------------------------------- FarragoJdbcParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { this.paramName = paramName; this.paramMetaData = paramMetaData; } //~ Methods ---------------------------------------------------------------- public String getParamName() { return paramName; } public FarragoParamFieldMetaData getParamMetaData() { return paramMetaData; } public Object scrubValue(Object x) { if (x == null) { checkNullable(); } return x; } public Object scrubValue(Object x, Calendar cal) { return scrubValue(x); //throw new UnsupportedOperationException(); } protected void checkNullable() { if (paramMetaData.nullable == ParameterMetaData.parameterNoNulls) { throw newNotNullable(); } } protected void checkRange( BigInteger value, BigInteger min, BigInteger max) { if ((value.compareTo(min) < 0) || (value.compareTo(max) > 0)) { throw newValueOutOfRange(value); } } protected void checkRange(long value, long min, long max) { if ((value < min) || (value > max)) { // For JDK 1.4 compatibility throw newValueOutOfRange(new Long(value)); //throw newValueOutOfRange(Long.valueOf(value)); } } protected void checkRange(double value, double min, double max) { if ((value < min) || (value > max)) { // For JDK 1.4 compatibility throw newValueOutOfRange(new Double(value)); //throw newValueOutOfRange(Double.valueOf(value)); } } /** * Returns an error that the value is not valid for the desired SQL type. */ protected EigenbaseException newInvalidType(Object x) { // TODO: Change to use client resources return new EigenbaseException( "Cannot assign a value of Java class " + x .getClass().getName() + " to parameter of type " + paramMetaData.paramTypeStr, null); //return FarragoResource.instance().ParameterValueIncompatible.ex( // x.getClass().getName(), // paramMetaData.paramTypeStr); } /** * Returns an error that the value is not nullable */ protected EigenbaseException newNotNullable() { // TODO: Change to use client resources return new EigenbaseException( "Cannot assign NULL to parameter '" + paramName + "' of type " + paramMetaData.paramTypeStr + " NOT NULL", null); //return FarragoResource.instance().ParameterValueNotNullable.ex( // paramMetaData.paramTypeStr); } /** * Returns an error that the value cannot be converted to the desired SQL * type. */ protected EigenbaseException newInvalidFormat(Object x) { // TODO: Change to use client resources return new EigenbaseException( "Value '" + x + "' cannot be converted to parameter of type " + paramMetaData.paramTypeStr, null); //return FarragoResource.instance().ParameterValueInvalidFormat.ex( // x.toString(), // paramMetaData.paramTypeStr); } /** * Returns an error the value is too long to be converted to the desired SQL * type. */ protected EigenbaseException newValueTooLong(Object x) { // TODO: Change to use client resources return new EigenbaseException( "Value '" + x + "' is too long for parameter of type " + paramMetaData.paramTypeStr, null); //return FarragoResource.instance().ParameterValueTooLong.ex( // x.toString(), // paramMetaData.paramTypeStr); } /** * Returns an error the value is out of range and cannot be converted to the * desired SQL type. */ protected EigenbaseException newValueOutOfRange(Object x) { // TODO: Change to use client resources return new EigenbaseException( "Value '" + x + "' is out of range for parameter of type " + paramMetaData.paramTypeStr, null); //return FarragoResource.instance().ParameterValueOutOfRange.ex( // x.toString(), // paramMetaData.paramTypeStr); } } // End FarragoJdbcParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcApproxParamDef.java0000444000175000017500000001060411173714170030167 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcApproxParamDef.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // Portions Copyright (C) 2006-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.math.*; import java.sql.*; /** * FarragoJdbcEngineApproxParamDef defines a approximate numeric parameter. This * class is JDK 1.4 compatible. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcApproxParamDef.java#10 $ */ class FarragoJdbcApproxParamDef extends FarragoJdbcParamDef { //~ Instance fields -------------------------------------------------------- final double min; final double max; //~ Constructors ----------------------------------------------------------- FarragoJdbcApproxParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); switch (paramMetaData.type) { case Types.REAL: min = -Float.MAX_VALUE; max = Float.MAX_VALUE; break; case Types.FLOAT: case Types.DOUBLE: min = -Double.MAX_VALUE; max = Double.MAX_VALUE; break; default: min = 0; max = 0; assert (false) : "Approximate paramMetaData expected"; } } //~ Methods ---------------------------------------------------------------- private Double getDouble(Object value) { if (value instanceof Number) { Number n = (Number) value; checkRange( n.doubleValue(), min, max); return new Double(n.doubleValue()); } else if (value instanceof Boolean) { return (((Boolean) value).booleanValue() ? new Double(1) : new Double(0)); } else if (value instanceof String) { try { BigDecimal bd = new BigDecimal(value.toString().trim()); return getDouble(bd); } catch (NumberFormatException ex) { throw newInvalidFormat(value); } } else { throw newInvalidType(value); } } private Float getFloat(Object value) { if (value instanceof Number) { Number n = (Number) value; checkRange( n.floatValue(), min, max); return new Float(n.floatValue()); } else if (value instanceof Boolean) { return (((Boolean) value).booleanValue() ? new Float(1) : new Float(0)); } else if (value instanceof String) { try { BigDecimal bd = new BigDecimal(value.toString().trim()); return getFloat(bd); } catch (NumberFormatException ex) { throw newInvalidFormat(value); } } else { throw newInvalidType(value); } } // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { if (x == null) { checkNullable(); return null; } else { switch (paramMetaData.type) { case Types.REAL: return getFloat(x); case Types.FLOAT: case Types.DOUBLE: return getDouble(x); default: throw new AssertionError("bad type " + paramMetaData.type); } } } } // End FarragoJdbcApproxParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/param/FarragoJdbcTimeParamDef.java0000444000175000017500000000704311173714170027617 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcTimeParamDef.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.param; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import org.eigenbase.util14.*; /** * FarragoJdbcEngineTimeParamDef defines a time parameter. * *

This class is JDK 1.4 compatible. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/param/FarragoJdbcTimeParamDef.java#10 $ */ class FarragoJdbcTimeParamDef extends FarragoJdbcParamDef { //~ Constructors ----------------------------------------------------------- public FarragoJdbcTimeParamDef( String paramName, FarragoParamFieldMetaData paramMetaData) { super(paramName, paramMetaData); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtParamDef public Object scrubValue(Object x) { return scrubValue( x, Calendar.getInstance()); } // implement FarragoSessionStmtParamDef // Converts parameters from timezone in calendar into gmt time. public Object scrubValue(Object x, Calendar cal) { if (x == null) { checkNullable(); return x; } if (x instanceof String) { String s = ((String) x).trim(); ZonelessTime zt = ZonelessTime.parse(s); if (zt == null) { throw newInvalidFormat(x); } return zt; } // Of the subtypes of java.util.Date, // only java.sql.Timestamp and java.sql.Time are OK. // java.sql.Date is not okay (no time information). if ((x instanceof Timestamp) || (x instanceof Time)) { java.util.Date timestamp = (java.util.Date) x; ZonelessTimestamp zt = new ZonelessTimestamp(); zt.setZonedTime(timestamp.getTime(), DateTimeUtil.getTimeZone(cal)); return zt; } // ZonelessDatetime is not required by JDBC, but we allow it because // it is a convenient format to serialize values over RMI. // We disallow ZonelessTime for the same reasons we disallow // java.sql.Time above. if ((x instanceof ZonelessTimestamp) || (x instanceof ZonelessTime)) { long time = ((ZonelessDatetime) x).getTime(); ZonelessTime zt = new ZonelessTime(); zt.setZonedTime(time, DateTimeUtil.getTimeZone(cal)); return zt; } throw newInvalidType(x); } } // End FarragoJdbcTimeParamDef.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/FarragoRJDriverPropertyInfo.java0000444000175000017500000000407111173714170027504 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoRJDriverPropertyInfo.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc; import java.sql.*; import org.objectweb.rmijdbc.*; /** * Serializable DriverPropertyInfo passed through RMI. * *

This class extends RmiJdbc's RJDriverPropertyInfo which implements {@link * java.io.Serializable} interface to pass the DriverPropertyInfo class from * server to client via RMI. * * @author Tim Leung * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoRJDriverPropertyInfo.java#11 $ */ public class FarragoRJDriverPropertyInfo extends RJDriverPropertyInfo implements java.io.Serializable { //~ Static fields/initializers --------------------------------------------- /** * SerialVersionUID created with JDK 1.5 serialver tool. */ private static final long serialVersionUID = -5324961535239009568L; //~ Constructors ----------------------------------------------------------- public FarragoRJDriverPropertyInfo(DriverPropertyInfo dpi) { super(dpi); } } ; // End FarragoRJDriverPropertyInfo.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/0000755000175000017500000000000011173714170022545 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoRJMedDataWrapper.java0000444000175000017500000001224111173714170030004 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoRJMedDataWrapper.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; import java.rmi.*; import java.sql.*; import java.util.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.jdbc.rmi.*; /** * Client-side JDBC implementation of {@link * net.sf.farrago.namespace.FarragoMedDataWrapper}. * *

It is paired with a FarragoRJMedDataWrapperServer via RMI. * * @author Tim Leung * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoRJMedDataWrapper.java#11 $ */ class FarragoRJMedDataWrapper implements FarragoMedDataWrapperInfo, java.io.Serializable { //~ Instance fields -------------------------------------------------------- protected final FarragoRJMedDataWrapperInterface rmiDataWrapper_; //~ Constructors ----------------------------------------------------------- public FarragoRJMedDataWrapper(FarragoRJMedDataWrapperInterface wrapper) { rmiDataWrapper_ = wrapper; } //~ Methods ---------------------------------------------------------------- public DriverPropertyInfo [] getPluginPropertyInfo( Locale locale, Properties wrapperProps) { try { return getDriverPropertyInfo( rmiDataWrapper_.getPluginPropertyInfo( locale, wrapperProps)); } catch (RemoteException e) { throw new RuntimeException(e.getMessage()); // TODO: add 'throws SQLException' to interface, and throw new // SQLException(e.getMessage()); } } public DriverPropertyInfo [] getServerPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps) { try { return getDriverPropertyInfo( rmiDataWrapper_.getServerPropertyInfo( locale, wrapperProps, serverProps)); } catch (RemoteException e) { throw new RuntimeException(e.getMessage()); // TODO: add 'throws SQLException' to interface, and throw new // SQLException(e.getMessage()); } } public DriverPropertyInfo [] getColumnSetPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps) { try { return getDriverPropertyInfo( rmiDataWrapper_.getColumnSetPropertyInfo( locale, wrapperProps, serverProps, tableProps)); } catch (RemoteException e) { throw new RuntimeException(e.getMessage()); // TODO: add 'throws SQLException' to interface, and throw new // SQLException(e.getMessage()); } } public DriverPropertyInfo [] getColumnPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps, Properties columnProps) { try { return getDriverPropertyInfo( rmiDataWrapper_.getColumnPropertyInfo( locale, wrapperProps, serverProps, tableProps, columnProps)); } catch (RemoteException e) { throw new RuntimeException(e.getMessage()); // TODO: add 'throws SQLException' to interface, and throw new // SQLException(e.getMessage()); } } public boolean isForeign() { try { return rmiDataWrapper_.isForeign(); } catch (RemoteException e) { throw new RuntimeException(e.getMessage()); // TODO: add 'throws SQLException' to interface, and throw new // SQLException(e.getMessage()); } } private DriverPropertyInfo [] getDriverPropertyInfo( FarragoRJDriverPropertyInfo [] infos) { DriverPropertyInfo [] dpis = new DriverPropertyInfo[infos.length]; for (int i = 0; i < infos.length; i++) { dpis[i] = infos[i].getPropertyInfo(); } return dpis; } } // End FarragoRJMedDataWrapper.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoRJConnection.java0000444000175000017500000001257411173714170027254 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoRJConnection.java#17 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; import java.rmi.*; import java.sql.*; import java.util.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.jdbc.rmi.*; import org.eigenbase.jdbc4.*; import org.objectweb.rmijdbc.*; /** * JDBC connection to Farrago across an RMI transport. * *

It is paired with an FarragoRJConnectionServer via RMI. * * @author Tim Leung * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoRJConnection.java#17 $ */ public class FarragoRJConnection extends UnwrappableRJConnection implements java.io.Serializable, FarragoConnection { //~ Static fields/initializers --------------------------------------------- /** * SerialVersionUID created with JDK 1.5 serialver tool. */ private static final long serialVersionUID = -3256212096290593733L; //~ Constructors ----------------------------------------------------------- protected FarragoRJConnection(RJConnectionInterface rmiconn) { super(rmiconn); } public FarragoRJConnection( RJDriverInterface drv, String url, Properties info) throws Exception { super(drv, url, info); } //~ Methods ---------------------------------------------------------------- private FarragoRJConnectionInterface getFarragoRmiCon() { return (FarragoRJConnectionInterface) rmiConnection_; } public long getFarragoSessionId() throws SQLException { try { return getFarragoRmiCon().getFarragoSessionId(); } catch (RemoteException e) { throw new SQLException(e.getMessage()); } } public String findMofId(String wrapperName) throws SQLException { try { return getFarragoRmiCon().findMofId(wrapperName); } catch (RemoteException e) { throw new SQLException(e.getMessage()); } } public FarragoMedDataWrapperInfo getWrapper( String mofId, String libraryName, Properties options) throws SQLException { try { final FarragoRJMedDataWrapperInterface wrapper = getFarragoRmiCon().getWrapper(mofId, libraryName, options); return new FarragoRJMedDataWrapper(wrapper); } catch (RemoteException e) { throw new SQLException(e.getMessage()); } } // // begin JDBC 4 methods // // implement Connection public Struct createStruct(String typeName, Object [] attributes) throws SQLException { throw new UnsupportedOperationException("createStruct"); } // implement Connection public Array createArrayOf(String typeName, Object [] elements) throws SQLException { throw new UnsupportedOperationException("createArrayOf"); } // implement Connection public Properties getClientInfo() throws SQLException { throw new UnsupportedOperationException("getClientInfo"); } // implement Connection public String getClientInfo(String name) throws SQLException { throw new UnsupportedOperationException("getClientInfo"); } // implement Connection public void setClientInfo(String name, String value) { throw new UnsupportedOperationException("setClientInfo"); } // implement Connection public void setClientInfo(Properties props) { throw new UnsupportedOperationException("setClientInfo"); } // implement Connection public boolean isValid(int timeout) { throw new UnsupportedOperationException("isValid"); } // implement Connection public SQLXML createSQLXML() throws SQLException { throw new UnsupportedOperationException("createSQLXML"); } // implement Connection public NClob createNClob() throws SQLException { throw new UnsupportedOperationException("createNClob"); } // implement Connection public Clob createClob() throws SQLException { throw new UnsupportedOperationException("createClob"); } // implement Connection public Blob createBlob() throws SQLException { throw new UnsupportedOperationException("createBlob"); } // // end JDBC 4 methods // } // End FarragoRJConnection.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/package.html0000444000175000017500000000130511173714170025023 0ustar drazzibdrazzib Package net.sf.farrago.jdbc.client Implements the client side of the Farrago JDBC driver.

NOTE jvs 2-Oct-2005: This package gets included in client-side code, so it must be source-compatible with JDK 1.4.

 

Revision $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/package.html#8 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcClientDriver.java0000444000175000017500000000712211173714170032636 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcClientDriver.java#6 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; import de.simplicit.vjdbc.*; import java.sql.*; import java.util.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.release.*; /** * FarragoUnregisteredJdbcClientDriver implements the Farrago client side of the * {@link java.sql.Driver} interface via the VJDBC proxy. It does not register * itself; for that, use {@link FarragoVjdbcClientDriver}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcClientDriver.java#6 $ */ public abstract class FarragoUnregisteredVjdbcClientDriver extends FarragoAbstractJdbcDriver { //~ Methods ---------------------------------------------------------------- /** * @return the prefix for JDBC URL's understood by this driver; subclassing * drivers can override this to customize the URL scheme */ public String getUrlPrefix() { return getBaseUrl() + "rmi://"; } // implement Driver public Connection connect( String url, Properties info) throws SQLException { if (!acceptsURL(url)) { return null; } // connection property precedence: // connect string (URI), info props, connection defaults // don't modify user's properties: // copy input props backed by connection defaults, // move any params from the URI to the properties Properties driverProps = applyDefaultConnectionProps(info); String driverUrl = parseConnectionParams(url, driverProps); Driver rmiDriver; try { rmiDriver = new VirtualDriver(); } catch (Exception ex) { // TODO: use FarragoJdbcUtil.newSqlException, see Jira FRG-122 throw new SQLException(ex.getMessage()); } // transform the URL into a form understood by VJDBC String urlRmi = driverUrl.substring(getUrlPrefix().length()); String [] split = urlRmi.split(":"); if (split.length == 1) { // no port number, so append default FarragoReleaseProperties props = FarragoReleaseProperties.instance(); urlRmi = urlRmi + ":" + props.jdbcUrlPortDefault.get(); } urlRmi = "jdbc:vjdbc:rmi://" + urlRmi + "/VJdbc,FarragoDBMS"; // NOTE: can't call DriverManager.connect here, because that // would deadlock in the case where client and server are // running in the same VM return rmiDriver.connect(urlRmi, driverProps); } } // End FarragoUnregisteredVjdbcClientDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoVjdbcClientDriver.java0000444000175000017500000000312011173714170030247 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoVjdbcClientDriver.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; /** * FarragoJdbcClientDriver implements the Farrago client side of the {@link * java.sql.Driver} interface via the VJDBC proxy. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoVjdbcClientDriver.java#7 $ */ public class FarragoVjdbcClientDriver extends FarragoUnregisteredVjdbcClientDriver { //~ Static fields/initializers --------------------------------------------- static { new FarragoVjdbcClientDriver().register(); } } // End FarragoVjdbcClientDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoVjdbcHttpClientDriver.java0000444000175000017500000000317211173714170031116 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoVjdbcHttpClientDriver.java#4 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; /** * FarragoJdbcHttpClientDriver implements the Farrago client side of the {@link * java.sql.Driver} interface via the VJDBC HTTP servlet proxy. * * @author Oscar Gothberg * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoVjdbcHttpClientDriver.java#4 $ */ public class FarragoVjdbcHttpClientDriver extends FarragoUnregisteredVjdbcHttpClientDriver { //~ Static fields/initializers --------------------------------------------- static { new FarragoVjdbcHttpClientDriver().register(); } } // End FarragoVjdbcHttpClientDriver.java ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrooteigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcHttpClientDriver.javaeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcHttpClientDriver.java0000444000175000017500000000756111173714170033505 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcHttpClientDriver.java#4 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; import de.simplicit.vjdbc.*; import java.sql.*; import java.util.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.release.*; /** * FarragoUnregisteredVJdbcHttpClientDriver implements the Farrago client side * of the {@link java.sql.Driver} interface via the VJDBC HTTP servlet proxy. It * does not register itself; for that, use {@link FarragoVjdbcHttpClientDriver}. * * @author Oscar Gothberg * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoUnregisteredVjdbcHttpClientDriver.java#4 $ */ public class FarragoUnregisteredVjdbcHttpClientDriver extends FarragoAbstractJdbcDriver { //~ Methods ---------------------------------------------------------------- /** * @return the prefix for JDBC URL's understood by this driver; subclassing * drivers can override this to customize the URL scheme */ public String getUrlPrefix() { // this should be refactored, along with it's sibling in the RMI driver, // the only reason this doesn't break it's caller in connect() is that // "farrago" and "luciddb" both happen to be 7 letter words return getBaseUrl() + "servlet:http://"; } public Connection connect(String url, Properties info) throws SQLException { if (!acceptsURL(url)) { return null; } // connection property precedence: // connect string (URI), info props, connection defaults // don't modify user's properties: // copy input props backed by connection defaults, // move any params from the URI to the properties Properties driverProps = applyDefaultConnectionProps(info); String driverUrl = parseConnectionParams(url, driverProps); Driver httpDriver; try { httpDriver = new VirtualDriver(); } catch (Exception ex) { // TODO: use FarragoJdbcUtil.newSqlException, see Jira FRG-122 throw new SQLException(ex.getMessage()); } // transform the URL into a form understood by VJDBC String urlHttp = driverUrl.substring(getUrlPrefix().length()); String [] split = urlHttp.split(":"); if (split.length == 1) { // no port number, so append default FarragoReleaseProperties props = FarragoReleaseProperties.instance(); urlHttp = urlHttp + ":" + props.jdbcUrlHttpPortDefault.get(); } urlHttp = "jdbc:vjdbc:servlet:http://" + urlHttp + "/vjdbc_servlet/vjdbc,FarragoDBMS"; // NOTE: can't call DriverManager.connect here, because that // would deadlock in the case where client and server are // running in the same VM return httpDriver.connect(urlHttp, driverProps); } } // End FarragoUnregisteredVjdbcHttpClientDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/client/FarragoJdbcClientDriver.java0000444000175000017500000001055411173714170030072 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoJdbcClientDriver.java#19 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.client; import java.sql.*; import java.util.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.release.*; import org.objectweb.rmijdbc.RJConnectionInterface; /** * FarragoJdbcClientDriver implements the Farrago client side of the {@link * java.sql.Driver} interface via the RmiJdbc proxy. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/client/FarragoJdbcClientDriver.java#19 $ */ public class FarragoJdbcClientDriver extends FarragoAbstractJdbcDriver { //~ Static fields/initializers --------------------------------------------- static { new FarragoJdbcClientDriver().register(); } //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoJdbcClientDriver object. */ public FarragoJdbcClientDriver() { } //~ Methods ---------------------------------------------------------------- /** * @return the prefix for JDBC URL's understood by this driver; subclassing * drivers can override this to customize the URL scheme */ public String getUrlPrefix() { return getBaseUrl() + "rmi://"; } // implement Driver public Connection connect( String url, Properties info) throws SQLException { if (!acceptsURL(url)) { return null; } // connection property precedence: // connect string (URI), info props, connection defaults // don't modify user's properties: // copy input props backed by connection defaults, // move any params from the URI to the properties Properties driverProps = applyDefaultConnectionProps(info); String driverUrl = parseConnectionParams(url, driverProps); Driver rmiDriver; try { rmiDriver = new CustomRJDriver(); } catch (Exception ex) { // TODO: use FarragoJdbcUtil.newSqlException, see Jira FRG-122 throw new SQLException(ex.getMessage()); } // transform the URL into a form understood by RmiJdbc String urlRmi = driverUrl.substring(getUrlPrefix().length()); String [] split = urlRmi.split(":"); if (split.length == 1) { // no port number, so append default FarragoReleaseProperties props = FarragoReleaseProperties.instance(); urlRmi = urlRmi + ":" + props.jdbcUrlPortDefault.get(); } urlRmi = "jdbc:rmi://" + urlRmi + "/" + getClientUrl(); // NOTE: can't call DriverManager.connect here, because that // would deadlock in the case where client and server are // running in the same VM return rmiDriver.connect(urlRmi, driverProps); } //~ Inner Classes ---------------------------------------------------------- private static class CustomRJDriver extends org.objectweb.rmijdbc.Driver implements java.sql.Driver, java.io.Serializable { CustomRJDriver() throws Exception { super(); } public java.sql.Connection buildConnection(RJConnectionInterface c) throws SQLException { return new FarragoRJConnection(c); } } } // End FarragoJdbcClientDriver.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/rmi/0000755000175000017500000000000011173714170022056 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/rmi/package.html0000444000175000017500000000114411173714170024335 0ustar drazzibdrazzib Package net.sf.farrago.jdbc.rmi Declares the remote interfaces by which the RMI JDBC client classes communicate with the RMI server.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/rmi/package.html#6 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/rmi/FarragoRJConnectionInterface.java0000444000175000017500000000427511173714170030405 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/rmi/FarragoRJConnectionInterface.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.rmi; import java.rmi.*; import java.sql.*; import java.util.*; import org.objectweb.rmijdbc.*; /** * RMI server interface corresponding to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper}. * * @author Tim Leung * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/rmi/FarragoRJConnectionInterface.java#11 $ */ public interface FarragoRJConnectionInterface extends RJConnectionInterface { //~ Methods ---------------------------------------------------------------- /** * @see net.sf.farrago.jdbc.FarragoConnection#getFarragoSessionId */ long getFarragoSessionId() throws RemoteException, SQLException; /** * @see net.sf.farrago.jdbc.FarragoConnection#getWrapper */ String findMofId(String wrapperName) throws RemoteException, SQLException; /** * @see net.sf.farrago.jdbc.FarragoConnection#getWrapper */ FarragoRJMedDataWrapperInterface getWrapper( String mofId, String libraryName, Properties options) throws RemoteException, SQLException; } // End FarragoRJConnectionInterface.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/rmi/FarragoRJMedDataWrapperInterface.java0000444000175000017500000000560011173714170031137 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/rmi/FarragoRJMedDataWrapperInterface.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc.rmi; import java.rmi.*; import java.util.*; import net.sf.farrago.jdbc.*; /** * RMI server interface corresponding to {@link * net.sf.farrago.jdbc.FarragoMedDataWrapperInfo}. * * @author Tim Leung * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/rmi/FarragoRJMedDataWrapperInterface.java#10 $ */ public interface FarragoRJMedDataWrapperInterface extends Remote { //~ Methods ---------------------------------------------------------------- /** * @see net.sf.farrago.jdbc.FarragoMedDataWrapperInfo#getPluginPropertyInfo */ FarragoRJDriverPropertyInfo [] getPluginPropertyInfo( Locale locale, Properties wrapperProps) throws RemoteException; /** * @see net.sf.farrago.jdbc.FarragoMedDataWrapperInfo#getServerPropertyInfo */ FarragoRJDriverPropertyInfo [] getServerPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps) throws RemoteException; /** * @see net.sf.farrago.jdbc.FarragoMedDataWrapperInfo#getColumnSetPropertyInfo */ FarragoRJDriverPropertyInfo [] getColumnSetPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps) throws RemoteException; /** * @see net.sf.farrago.jdbc.FarragoMedDataWrapperInfo#getColumnPropertyInfo */ FarragoRJDriverPropertyInfo [] getColumnPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps, Properties columnProps) throws RemoteException; /** * @see net.sf.farrago.jdbc.FarragoMedDataWrapperInfo#isForeign */ boolean isForeign() throws RemoteException; } // End FarragoRJMedDataWrapperInterface.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/FarragoMedDataWrapperInfo.java0000444000175000017500000001234511173714170027113 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoMedDataWrapperInfo.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc; import java.sql.*; import java.util.*; /** * Description of a SQL/MED data wrapper. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoMedDataWrapperInfo.java#11 $ */ public interface FarragoMedDataWrapperInfo { //~ Methods ---------------------------------------------------------------- /** * Obtains information about the properties applicable to plugin * initialization. * * @param locale Locale for formatting property info * @param wrapperProps proposed list of property name/value pairs which will * be sent to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#initialize} * * @return 0 or more property info descriptors */ public DriverPropertyInfo [] getPluginPropertyInfo( Locale locale, Properties wrapperProps); /** * Obtains information about the properties applicable to server * initialization (the props parameter to the newServer method). * * @param locale Locale for formatting property info * @param wrapperProps proposed list of property name/value pairs which will * be sent to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#initialize} * @param serverProps proposed list of property name/value pairs which will * be sent to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#newServer} * * @return 0 or more property info descriptors */ public DriverPropertyInfo [] getServerPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps); /** * Obtains information about the properties applicable to column set * initialization (the tableProps parameter to the newColumnSet method). * * @param locale Locale for formatting property info * @param wrapperProps proposed list of property name/value pairs which will * be sent to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#initialize} * @param serverProps proposed list of property name/value pairs which will * be sent to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#newServer} * @param tableProps proposed list of property name/value pairs which will * be sent to the tableProps parameter of {@link * net.sf.farrago.namespace.FarragoMedDataServer#newColumnSet} * * @return 0 or more property info descriptors */ public DriverPropertyInfo [] getColumnSetPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps); /** * Obtains information about the properties applicable to individual column * initialization (the columnPropMap parameter to the {@link * net.sf.farrago.namespace.FarragoMedDataServer#newColumnSet} method). * * @param locale Locale for formatting property info * @param wrapperProps proposed list of property name/value pairs which will * be sent to {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#initialize} * @param serverProps proposed list of property name/value pairs which will * be sent to FarragoMedDataWrapper.newServer() {@link * net.sf.farrago.namespace.FarragoMedDataWrapper#newServer} * @param tableProps proposed list of property name/value pairs which will * be sent as the tableProps parameter of {@link * net.sf.farrago.namespace.FarragoMedDataServer#newColumnSet} * @param columnProps proposed list of property name/value pairs which will * be sent as an entry in the columnPropMap parameter of {@link * net.sf.farrago.namespace.FarragoMedDataServer#newColumnSet} * * @return 0 or more property info descriptors */ public DriverPropertyInfo [] getColumnPropertyInfo( Locale locale, Properties wrapperProps, Properties serverProps, Properties tableProps, Properties columnProps); /** * Determines whether this data wrapper accesses foreign data, or manages * local data. * * @return true for foreign data; false for local data */ public boolean isForeign(); } // End FarragoMedDataWrapperInfo.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/FarragoConnection.java0000444000175000017500000000364711173714170025543 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoConnection.java#12 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc; import java.sql.*; import java.util.*; /** * JDBC connection to Farrago. * *

This interface extends the usual {@link java.sql.Connection} interface to * include methods for interrogating SQL/MED wrappers and data servers, and to * expose the farrago session identifier. * * @author jhyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoConnection.java#12 $ */ public interface FarragoConnection extends java.sql.Connection { //~ Methods ---------------------------------------------------------------- long getFarragoSessionId() throws SQLException; String findMofId(String wrapperName) throws SQLException; FarragoMedDataWrapperInfo getWrapper( String mofId, String libraryName, Properties options) throws SQLException; } // End FarragoConnection.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/FarragoJdbcUtil.java0000444000175000017500000004657411173714170025152 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoJdbcUtil.java#17 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc; import java.io.*; import java.lang.reflect.*; import java.sql.*; import java.util.*; import java.util.logging.*; import java.util.regex.*; import org.eigenbase.util.*; import org.eigenbase.util14.*; /** * Utility functions for the Farrago JDBC driver. * *

This class is JDK 1.4 compatible. * * @author angel * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoJdbcUtil.java#17 $ * @since Mar 18, 2006 */ public class FarragoJdbcUtil { // NOTE jvs 7-Oct-2008: the untested serialization support in this class is // used by extension projects which make use of RmiJdbc. VJDBC-based // projects neither need nor use this support. Applications which // load the Farrago engine driver directly may use it (intentionally // or unintentionally) by attempting to serialize exceptions // thrown via Farrago JDBC. //~ Static fields/initializers --------------------------------------------- /** * Contains the serialization checker for each thread. */ private static final ThreadLocal /**/ threadChecker = new ThreadLocal /**/() { protected Object /*SerializationChecker*/ initialValue() { return new SerializationChecker(); } }; //~ Methods ---------------------------------------------------------------- /** * Converts any Throwable to a SQLException. * * @param ex Throwable to be converted * @param tracer Logger on which to trace exceptions as they are converted; * must not be null * * @return ex as a SQLException */ public static SQLException newSqlException( final Throwable ex, Logger tracer) { final String message = ex.getMessage(); tracer.severe(message); tracer.throwing("FarragoJdbcUtil", "newSqlException(ex)", ex); Throwable cause = ex.getCause(); SQLException sqlExcn; if (ex instanceof EigenbaseException) { String stmt = null; if (ex instanceof EigenbaseContextException) { stmt = ((EigenbaseContextException) ex).getOriginalStatement(); } // TODO: map for SQLState if (cause instanceof EigenbaseValidatorException) { // We're looking at // ex = "Validation error at line 5, column 10" // ex.cause = "Bad column 'FOO'" // so the message should be // "Validation error at line 5, column 10: Bad column 'FOO'" final String causeMessage = cause.getMessage(); //noinspection ThrowableInstanceNeverThrown sqlExcn = new FarragoSqlException( message + ": " + causeMessage, ex, stmt, null); // Discard this cause and move on to next. cause = cause.getCause(); } else { //noinspection ThrowableInstanceNeverThrown sqlExcn = new FarragoSqlException(message, ex, stmt, null); } } else if (ex instanceof SQLException) { sqlExcn = (SQLException) ex; } else { // for anything else, include the class name // as part of what went wrong //noinspection ThrowableInstanceNeverThrown sqlExcn = new FarragoSqlException( ex.getClass().getName() + ": " + message, ex, null, null); } // preserve additional attributes of the original excn sqlExcn.setStackTrace(ex.getStackTrace()); // Convert to SQLException-style chaining. That means that the // underlying cause -- that is, the exception at the end of the cause // chain -- comes out on top. // // If this is a parse exception, the underlying cause will be a // generated class specific to our particular parser implementation, so // we stop at the SqlParseException which is just above it. if (cause == null) { return sqlExcn; } else if (ex instanceof EigenbaseParserException) { return sqlExcn; } else { // NOTE jvs 18-June-2004: reverse the order so that // the underlying cause comes out on top SQLException sqlCause = newSqlException(cause, tracer); sqlCause.setNextException(sqlExcn); return sqlCause; } } /** * Creates a new SQLException. * * @param message detail message, the reason for this exception * @param tracer Logger on which to trace new exceptions; must not be * null * * @return new SQLException */ public static SQLException newSqlException( final String message, Logger tracer) { //noinspection ThrowableInstanceNeverThrown SQLException ex = new SQLException(message); // REVIEW: not sure tracing everything is desirable. Consider // allowing/testing for null tracer, or creating an alternative // newSqlException(message) method. tracer.severe(message); tracer.throwing("FarragoJdbcUtil", "newSqlException(msg)", ex); return ex; } /** * Walks an exception stack using reflection looking for the original SQL * statement that MAY be in the exception stack. * * @param ex top of exception stack * * @return Original input text that generated the error or null */ public static String findInputString(final Throwable ex) { Class clazz = ex.getClass(); // Check to see if the current exception has the string we are looking // for. try { // EigenbaseContextException and FarragoSqlException both have a // getOriginalStatement() method. Method meth = clazz.getMethod("getOriginalStatement", (Class []) null); Object valObj = meth.invoke(ex, (Object []) null); if (valObj != null) { return (String) valObj; } } catch (IllegalAccessException e) { //intentionally empty } catch (NoSuchMethodException e) { //intentionally empty } catch (InvocationTargetException e) { //intentionally empty } // Here is where is starts getting tricky. Parser and Validator chain // expceptions in different ways. Parser exceptions use the "next" // field of java.lang.SQLException while the validator chains through // the "original" field defined in FarragoSqlException. None of the // methods seem to use the "cause" field defined by Throwable. // // Since the parser can have entries in both "original" and "next" we // will try "next" first. try { // SQLException has a method getNextException() Method meth = clazz.getMethod("getNextException", (Class []) null); Object valObj = meth.invoke(ex, (Object []) null); if ((valObj != null) && ((Throwable) valObj != ex)) { String query = findInputString((Throwable) valObj); if (query != null) { return query; } } } catch (IllegalAccessException e) { // intentionally empty } catch (NoSuchMethodException e) { // intentionally empty } catch (InvocationTargetException e) { // intentionally empty } // Check for the original cause try { // FarragoSqlException has a method getOriginalThrowable(). Method meth = clazz.getMethod("getOriginalThrowable", (Class []) null); Object valObj = meth.invoke(ex, (Object []) null); if ((valObj != null) && ((Throwable) valObj != ex)) { return findInputString((Throwable) valObj); } } catch (IllegalAccessException e) { // intentionally empty } catch (NoSuchMethodException e) { // intentionally empty } catch (InvocationTargetException e) { // intentionally empty } return null; } //~ Inner Classes ---------------------------------------------------------- /** * Tests whether an object (in particular an exception) is serializable. * Maintains a list of objects actively being tested so that we do not * recursively test the same object. */ private static class SerializationChecker { /** * What classes should not be serialized. In particular: * org.eigenbase.sql.parser.SqlParseException * org.eigenbase.sql.parser.SqlParserPos org.eigenbase.sql.SqlNode (and * subclasses) net.sf.farrago.parser.impl.Token and ParseException or * ...parser.impl.Token and ParseException in Aspen */ private final static Pattern NON_SERIALIAZABLE_CLASSES = Pattern.compile( "org\\.eigenbase\\.sql\\..*" + '|' + ".*\\.parser\\.impl\\.[^.]*"); private final Set /**/ active = new HashSet /**/(); /** * Whether the client has the RMI class loader enabled. If true, * serializabilty is sufficient. If false, the class also has to be * available on the client. */ private final boolean rmiClassLoader = false; /** * Converts a {@code Throwable} into a similar exception that is * serializable. The original object, or at least its cause, is used if * possible; and the new throwable has the same stack trace. * * @param throwable Exception * * @return Exception that is serializable and of the same general type */ Throwable makeSerializable(Throwable throwable) { // REVIEW: Is serializability sufficient? The class may not be // available on the client. if (isSerializable(throwable)) { return throwable; } Throwable cause = throwable.getCause(); if (cause == throwable) { cause = null; } if (cause != null) { cause = makeSerializable(cause); } String message = throwable.getClass().getName() + ": " + throwable.getMessage(); Throwable serializable; if (throwable instanceof RuntimeException) { //noinspection ThrowableInstanceNeverThrown serializable = new RuntimeException(message, cause); } else if (throwable instanceof Exception) { //noinspection ThrowableInstanceNeverThrown serializable = new Exception(message, cause); } else if (throwable instanceof Error) { //noinspection ThrowableInstanceNeverThrown serializable = new Error(message, cause); } else { //noinspection ThrowableInstanceNeverThrown serializable = new Throwable(message, cause); } serializable.setStackTrace(throwable.getStackTrace()); return serializable; } /** * Returns whether an object is serializable. * * @param o Object * * @return Whether object is serializable */ boolean isSerializable(Object o) { if (!rmiClassLoader) { String className = o.getClass().getName(); if (NON_SERIALIAZABLE_CLASSES.matcher(className).matches()) { return false; } } if (!active.add(o)) { // The object is already being tested for serialization. Tell a // white lie and say that it is serializable. If it is not // serializable, the first call will find out. return true; } try { ObjectOutputStream oos = new ObjectOutputStream( new ByteArrayOutputStream()); oos.writeObject(o); return true; } catch (NotSerializableException e) { if (o instanceof EigenbaseParserException) { // We know there are problems serializing // EigenbaseParserException: specifically, the cause of a // SqlParseException is usually a ParseException generated // by JavaCC, and this is not serializable because it // contains // Token. } else if (o instanceof Serializable) { // If you get this error, you should fix the class and make // sure all of its fields are types that extend // Serializable. Then as long as the instances of those // types are being honest, everything should be hunky dory. System.out.println( "Warning: Object [" + o + "] of class " + o.getClass() + " implements Serializable but is not serializable. " + "Error is as follows:"); e.printStackTrace(System.out); } return false; } catch (IOException e) { throw new RuntimeException( "Error while testing serializability", e); } finally { active.remove(o); } } } /** * Exception thrown by Farrago JDBC driver. * *

The exception contains the original, undiluted exception for more * detailed diagnostics. This is used by the testing infrastructure to * ensure that the error occurs at the right (line, col) thru (line, col) * position. * *

The original exception is returned by the {@link * #getOriginalThrowable()} method, but will not be returned from the * standard {@link #getNextException()} or {@link #getCause()} methods; this * exception therefore behaves exactly like a regular {@link * java.sql.SQLException}. */ public static class FarragoSqlException extends SQLException { /** * SerialVersionUID created with JDK 1.5 serialver tool. */ private static final long serialVersionUID = -2302810435386763566L; /** * Original exception. */ private final Throwable original; private final String originalStatement; /** * Creates an exception with a message and a record of the undiluted * original exception. * * @param reason A description of the exception * @param original Original exception * @param originalStatement Original statement */ public FarragoSqlException( String reason, Throwable original, String originalStatement, Throwable cause) { super(reason); initCause(cause); this.original = original; this.originalStatement = originalStatement; } /** * Returns the original exception. * * @return original exception */ public Throwable getOriginalThrowable() { return original; } /** * Returns the original statement. * * @return original statement */ public String getOriginalStatement() { return originalStatement; } /** * Per {@link java.io.Serializable} API, provides a replacement object * to be written during serialization. * *

This implementation converts this FarragoSqlException into an * exception that looks similar but is serializable. */ private Object writeReplace() { boolean needNewException = false; Throwable serializableOriginal; final SerializationChecker checker = (SerializationChecker) threadChecker.get(); // Replace original if it is not serializable. if ((original != null) && (original != this) && !checker.isSerializable(original)) { needNewException = true; serializableOriginal = checker.makeSerializable(original); } else { serializableOriginal = original; } // Replace next if it is not serializable. final SQLException next = getNextException(); SQLException serializableNext; if ((next != null) && (next != this) && !checker.isSerializable(next)) { needNewException = true; serializableNext = (SQLException) checker.makeSerializable(next); } else { serializableNext = next; } final Throwable cause = getCause(); Throwable serializableCause; if ((cause != null) && (cause != this) && !checker.isSerializable(cause)) { needNewException = true; serializableCause = checker.makeSerializable(cause); } else { serializableCause = cause; } // If original, next and cause are all serializable, we can use the // original exception. Otherwise we need a new exception with the // non-serializable parts replaced. if (needNewException) { //noinspection ThrowableInstanceNeverThrown final FarragoSqlException fse = new FarragoSqlException( getMessage(), serializableOriginal, originalStatement, serializableCause); fse.setNextException(serializableNext); return fse; } else { return this; } } } } // End FarragoJdbcUtil.java eigenbase-farrago-0.9.0/src/net/sf/farrago/jdbc/FarragoStatement.java0000444000175000017500000000370611173714170025404 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoStatement.java#9 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.jdbc; import java.sql.*; /** * Extends the usual {@link java.sql.Statement} interface with farrago features, * viz exposes the farrago statement identifier. * * @author mberkowitz * @version $Id: //open/dev/farrago/src/net/sf/farrago/jdbc/FarragoStatement.java#9 $ */ public interface FarragoStatement extends java.sql.Statement { //~ Instance fields -------------------------------------------------------- final String ERRMSG_NOT_A_QUERY = "Not a query: "; final String ERRMSG_IS_A_QUERY = "Can't executeUpdate a query: "; final String ERRMSG_REQ_NON_NEG = "Requires non-negative argument: "; //~ Methods ---------------------------------------------------------------- /** * @return a non-zero identifier, unique for each executing statement */ long getFarragoExecutingStmtId() throws SQLException; } // End FarragoStatement.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/0000755000175000017500000000000011173714170020752 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSessionExecutingStmtInfo.java0000444000175000017500000000647311173714170030360 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionExecutingStmtInfo.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import net.sf.farrago.session.*; /** * Implements the {@link FarragoSessionExecutingStmtInfo} interface in the * context of a {@link FarragoDbStmtContext}. * * @author Jason Ouellette * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionExecutingStmtInfo.java#8 $ */ public class FarragoDbSessionExecutingStmtInfo implements FarragoSessionExecutingStmtInfo { //~ Instance fields -------------------------------------------------------- private long id; private FarragoSessionStmtContext stmt; private FarragoDatabase database; private String sql; private long startTime; private List parameters; private List objectsInUse; //~ Constructors ----------------------------------------------------------- FarragoDbSessionExecutingStmtInfo( FarragoSessionStmtContext stmt, FarragoDatabase database, String sql, List parameters, List objectsInUse) { this.stmt = stmt; this.database = database; this.id = database.getUniqueId(); this.sql = sql; this.startTime = System.currentTimeMillis(); this.parameters = Collections.unmodifiableList(parameters); this.objectsInUse = Collections.unmodifiableList(objectsInUse); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionExecutingStmtInfo public FarragoSessionStmtContext getStmtContext() { return stmt; } FarragoDatabase getDatabase() { return database; } // implement FarragoSessionExecutingStmtInfo public long getId() { return id; } // implement FarragoSessionExecutingStmtInfo public String getSql() { return sql; } // implement FarragoSessionExecutingStmtInfo public List getParameters() { return parameters; } // implement FarragoSessionExecutingStmtInfo public long getStartTime() { return startTime; } // implement FarragoSessionExecutingStmtInfo public List getObjectsInUse() { return objectsInUse; } } // End FarragoDbSessionExecutingStmtInfo.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSessionPrivilegeMap.java0000444000175000017500000001014211173714170027311 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionPrivilegeMap.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import javax.jmi.reflect.*; import net.sf.farrago.session.*; import org.eigenbase.jmi.*; /** * FarragoDbSessionPrivilegeMap is a default implementation for {@link * FarragoSessionPrivilegeMap}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionPrivilegeMap.java#7 $ */ class FarragoDbSessionPrivilegeMap implements FarragoSessionPrivilegeMap { // TODO jvs 13-Aug-2005: factor out MultiMapUnique or whatever it's called //~ Instance fields -------------------------------------------------------- private final JmiModelView modelView; private final Map> mapTypeToSet; //~ Constructors ----------------------------------------------------------- FarragoDbSessionPrivilegeMap(JmiModelView modelView) { this.modelView = modelView; mapTypeToSet = new HashMap>(); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionPrivilegeMap public void mapPrivilegeForType( RefClass refClass, String privilegeName, boolean isLegal, boolean includeSubclasses) { if (includeSubclasses) { JmiClassVertex classVertex = modelView.getModelGraph().getVertexForRefClass(refClass); for ( JmiClassVertex jmiClassVertex : modelView.getAllSubclassVertices(classVertex)) { classVertex = (JmiClassVertex) jmiClassVertex; mapPrivilegeForType( classVertex.getRefClass(), privilegeName, isLegal, false); } return; } Set set = mapTypeToSet.get(refClass); if (!isLegal) { if (set == null) { return; } set.remove(privilegeName); return; } if (set == null) { set = new TreeSet(); mapTypeToSet.put(refClass, set); } set.add(privilegeName); } // implement FarragoSessionPrivilegeMap public Set getLegalPrivilegesForType(RefClass refClass) { Set set = mapTypeToSet.get(refClass); if (set == null) { return Collections.emptySet(); } return set; } void makeImmutable() { Iterator>> iter = mapTypeToSet.entrySet().iterator(); while (iter.hasNext()) { Map.Entry> entry = iter.next(); Set set = entry.getValue(); if (set.isEmpty()) { iter.remove(); } else if (set.size() == 1) { entry.setValue( Collections.singleton( set.iterator().next())); } else { entry.setValue(Collections.unmodifiableSet(set)); } } } } // End FarragoDbSessionPrivilegeMap.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSingleton.java0000444000175000017500000002705711173714170025340 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSingleton.java#16 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import java.util.logging.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; /** * FarragoDbSingleton manages a singleton instance of FarragoDatabase. It is * reference-counted to allow it to be shared in a library environment such as * the directly embedded JDBC driver. Note that all synchronization is done at * the class level, not the object level. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSingleton.java#16 $ */ public abstract class FarragoDbSingleton extends FarragoCompoundAllocation { //~ Static fields/initializers --------------------------------------------- protected static final Logger tracer = FarragoTrace.getDatabaseTracer(); /** * Reference count. */ private static int nReferences; // TODO jvs 14-Dec-2005: make instance private instead of protected // once FarragoDatabase no longer extends FarragoDbSingleton /** * Singleton instance, or null when nReferences == 0. */ protected static FarragoDatabase instance; /** * Flag indicating whether FarragoDbSingleton is already in {@link * #shutdown()}, to help prevent recursive shutdown. */ private static boolean inShutdown; /** * Flag indicating whether a database backup is already in progress */ private static boolean backupInProgress; /** * Flag indicating whether FarragoDbSingleton is already in {@link * #shutdownConditional(int)}, to help prevent recursive shutdown. */ private static boolean inShutdownConditional; //~ Methods ---------------------------------------------------------------- /** * Establishes a database reference. If this is the first reference, the * database will be loaded first; otherwise, the existing database is reused * with an increased reference count. * * @param sessionFactory factory for various database-level objects * * @return loaded database */ public static synchronized FarragoDatabase pinReference( FarragoSessionFactory sessionFactory) { tracer.info("connect"); ++nReferences; if (nReferences == 1) { assert (instance == null); boolean success = false; try { FarragoDatabase newDb = new FarragoDatabase(sessionFactory, false); assert (newDb == instance); success = true; } finally { if (!success) { nReferences = 0; instance = null; } } } return instance; } /** * Establishes a database reference. If requireExistingEngine, a new * database will not be loaded, even if this is the first reference. * * @param sessionFactory factory for various database-level objects * @param requireExistingEngine true if require an already created reference * * @return loaded database */ public static synchronized FarragoDatabase pinReference( FarragoSessionFactory sessionFactory, boolean requireExistingEngine) { if (requireExistingEngine) { tracer.info("connect"); if (instance == null) { throw FarragoResource.instance().NoDatabaseLoaded.ex(); } ++nReferences; return instance; } return pinReference(sessionFactory); } static synchronized void addSession( FarragoDatabase db, FarragoDbSession session) { assert (db == instance); db.addAllocation(session); } static synchronized void disconnectSession(FarragoDbSession session) { tracer.info("disconnect"); FarragoDatabase db = session.getDatabase(); assert (nReferences > 0); assert (db == instance); db.forgetAllocation(session); nReferences--; } /** * Retrieve a list of connected FarragoSession objects. Each invocation * produces a new List. Altering the list has no effect on the given * FarragoDatabase. * *

The returned FarragoSession objects may be disconnected at any time. * See {@link FarragoSession#isClosed()}. * * @param db sessions are retrieved from this FarragoDatabase instance * * @return non-null List of FarragoSession objects */ public static synchronized List getSessions( FarragoDatabase db) { List sessions = new ArrayList(); for (Object allocation : db.allocations) { if (allocation instanceof FarragoSession) { sessions.add((FarragoSession) allocation); } } return sessions; } public static synchronized List getSessions() { assert (instance != null); return getSessions(instance); } /** * Conditionally shuts down the database depending on the number of * references. * * @param groundReferences threshold for shutdown; if actual number of * sessions is greater than this, no shutdown takes place * * @return whether shutdown took place */ public static boolean shutdownConditional(int groundReferences) { boolean flushCodeCache = false; boolean success = false; synchronized (FarragoDbSingleton.class) { if (instance == null) { assert (nReferences == 0); return true; } if (inShutdownConditional || inShutdown) { return false; } inShutdownConditional = true; try { tracer.fine("ground reference count = " + groundReferences); tracer.fine("actual reference count = " + nReferences); int numLoopbackSessions = countLoopbackSessions(); if ((nReferences - numLoopbackSessions) <= groundReferences) { flushCodeCache = true; } success = true; } finally { // Clean up if an exception is being thrown if (!success) { inShutdownConditional = false; } } } // Release the monitor on FarragoDbSingleton: Allows loopback sessions // to be closed from other threads. It is possible that a new // connection (or even loopback session) will created while the // monitor is free. In that case, we will not shut down. It is also // possible some loopback sessions will not actually be closed by // the flush (connection resource leak, timing, etc.), in which case // we will not shut down. if (flushCodeCache) { instance.flushCodeCache(); } synchronized (FarragoDbSingleton.class) { try { if (nReferences <= groundReferences) { shutdown(); return true; } else { return false; } } finally { inShutdownConditional = false; } } } /** * Shuts down the database, killing any running sessions. */ public static void shutdown() { // REVIEW: SWZ 12/31/2004: If an extension project adds "specialized // initialization" that ends up pinning a reference to FarragoDatabase // (e.g. it opens a Connection so that it can execute SQL statements), // then the extension's specialized shutdown should close the // connection. When it does, FarragoSessionFactory.cleanupSessions() // will be invoked and calls shutdownConditional() -- resulting in a // recursive call to shutdown. The inShutdown field blocks this, but // there's probably a better way -- maybe a new implementation of // Connection that represents an internal connection and avoids the // extra reference count and cleanupSessions() call. // SWZ: 09/12/2008: Note that loopback sessions don't really solve // the above problem. Loopback sessions are sessions (connections) // owned by data wrappers/servers which can be closed by flushing // the code cache. boolean flushCodeCache = false; synchronized (FarragoDbSingleton.class) { if (instance == null) { assert (nReferences == 0); return; } if (inShutdown) { return; } inShutdown = true; tracer.info("shutdown"); if (countLoopbackSessions() > 0) { flushCodeCache = true; } } // Attempt to close loopback sessions. We will shut down even if // none close. if (flushCodeCache) { instance.flushCodeCache(); } synchronized (FarragoDbSingleton.class) { assert (instance != null); try { instance.sessionFactory.specializedShutdown(); instance.close(false); } finally { instance = null; nReferences = 0; inShutdown = false; } } } private static int countLoopbackSessions() { int numLoopbackSessions = 0; for (FarragoSession session : getSessions()) { if (session.isLoopback()) { numLoopbackSessions++; } } return numLoopbackSessions; } /** * @return true if the single currently exists */ public static boolean isReferenced() { if (nReferences > 0) { assert (instance != null); return true; } else { assert (instance == null); return false; } } /** * Sets a flag indicating whether a backup is in progress. If the flag is * true and a backup is already in progress, then false is returned. * Otherwise, true is returned. * * @param inProgress true if the flag is to be set, indicating that a backup * is in progress * * @return true if setting of the flag was successful */ public static synchronized boolean setBackupFlag(boolean inProgress) { if (inProgress && backupInProgress) { return false; } backupInProgress = inProgress; return true; } } // End FarragoDbSingleton.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbNullTxnMgr.java0000444000175000017500000001425311173714170025442 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbNullTxnMgr.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import java.util.concurrent.atomic.*; import net.sf.farrago.session.*; import net.sf.farrago.type.runtime.*; import org.eigenbase.relopt.*; /** * FarragoDbNullTxnMgr is a do-nothing implementation of {@link * FarragoSessionTxnMgr}. It is useful as a base class because it has a default * implementation for generating new transaction ID's and notifying listeners. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbNullTxnMgr.java#7 $ */ public class FarragoDbNullTxnMgr implements FarragoSessionTxnMgr { //~ Instance fields -------------------------------------------------------- private final AtomicLong nextId; private final List listeners; //~ Constructors ----------------------------------------------------------- public FarragoDbNullTxnMgr() { nextId = new AtomicLong(1); listeners = new ArrayList(); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionTxnMgr public void addListener( FarragoSessionTxnListener listener) { listeners.add(listener); } // implement FarragoSessionTxnMgr public void removeListener( FarragoSessionTxnListener listener) { listeners.remove(listener); } // implement FarragoSessionTxnMgr public FarragoSessionTxnId beginTxn(FarragoSession session) { FarragoSessionTxnId newId = new LongTxnId(nextId.getAndIncrement()); for (FarragoSessionTxnListener listener : listeners) { listener.transactionBegun(session, newId); } return newId; } // implement FarragoSessionTxnMgr public void accessTables( FarragoSessionTxnId txnId, TableAccessMap accessMap) { // NOTE jvs 17-Mar-2006: We reorder table accesses to minimize spurious // deadlocks. Take write locks before read locks because read->write // upgrade is a very common deadlock. And sort by table name so that // all statements use the same ordering. List> tableNames = new ArrayList>( accessMap.getTablesAccessed()); Collections.sort( tableNames, new CharStringComparator()); // TODO jvs 17-Mar-2006: use a LockOrderComparator to do // the job more cleanly. // First deal with WRITE_ACCESS and READWRITE_ACCESS. for (List tableName : tableNames) { TableAccessMap.Mode accessType = accessMap.getTableAccessMode(tableName); if (accessType == TableAccessMap.Mode.READ_ACCESS) { continue; } accessTablePrivate( txnId, tableName, accessType); } // Then deal with READ_ACCESS. for (List tableName : tableNames) { TableAccessMap.Mode accessType = accessMap.getTableAccessMode(tableName); if (accessType != TableAccessMap.Mode.READ_ACCESS) { continue; } accessTablePrivate( txnId, tableName, accessType); } } private void accessTablePrivate( FarragoSessionTxnId txnId, List localTableName, TableAccessMap.Mode accessType) { for (FarragoSessionTxnListener listener : listeners) { listener.tableAccessed(txnId, localTableName, accessType); } accessTable(txnId, localTableName, accessType); } /** * Called by accessTables for each table accessed. Default implementation is * to do nothing; subclasses override this to take real actions such as * calling a lock manager. * * @param txnId ID of accessing transaction * @param localTableName qualified name of table as it is known in the local * catalog * @param accessType type of table access */ protected void accessTable( FarragoSessionTxnId txnId, List localTableName, TableAccessMap.Mode accessType) { } // implement FarragoSessionTxnMgr public void endTxn( FarragoSessionTxnId txnId, FarragoSessionTxnEnd endType) { for (FarragoSessionTxnListener listener : listeners) { listener.transactionEnded(txnId, endType); } } //~ Inner Classes ---------------------------------------------------------- private static class LongTxnId implements FarragoSessionTxnId { private final long id; LongTxnId(long id) { this.id = id; } public String toString() { return Long.toString(id); } public boolean equals(Object obj) { if (!(obj instanceof LongTxnId)) { return false; } LongTxnId other = (LongTxnId) obj; return id == other.id; } public int hashCode() { return (int) id; } } } // End FarragoDbNullTxnMgr.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSessionInfo.java0000444000175000017500000000653711173714170025635 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionInfo.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import java.util.concurrent.*; import net.sf.farrago.session.*; /** * Implements the {@link FarragoSessionInfo} interface in the context of a * {@link FarragoDbSession}. * * @author Jason Ouellette * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionInfo.java#8 $ */ public class FarragoDbSessionInfo implements FarragoSessionInfo { //~ Instance fields -------------------------------------------------------- private long id; private FarragoSession session; private FarragoDatabase database; private Map statements; // REVIEW mberkowitz 28-Mar-2006: maybe have 1 map id->info in // FarragoDatabase. //~ Constructors ----------------------------------------------------------- FarragoDbSessionInfo(FarragoSession session, FarragoDatabase database) { this.id = database.getUniqueId(); this.session = session; this.database = database; statements = new ConcurrentHashMap(); } //~ Methods ---------------------------------------------------------------- public FarragoSession getSession() { return session; } FarragoDatabase getDatabase() { return database; } public long getId() { return id; } // implement FarragoSessionInfo public List getExecutingStmtIds() { Set s = statements.keySet(); Long [] k = statements.keySet().toArray(new Long[s.size()]); return Collections.unmodifiableList(Arrays.asList(k)); } // implement FarragoSessionInfo public FarragoSessionExecutingStmtInfo getExecutingStmtInfo(Long id) { return statements.get(id); } /** * Adds a running statement. * * @param info Info object for the running statement */ public void addExecutingStmtInfo(FarragoSessionExecutingStmtInfo info) { statements.put( info.getId(), info); } /** * Removes a running statement. * * @param id Unique identifier of a running statement */ public void removeExecutingStmtInfo(long id) { statements.remove(id); } } // End FarragoDbSessionInfo.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSession.java0000444000175000017500000015000211173714170025004 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSession.java#101 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.sql.*; import java.util.*; import java.util.logging.*; import java.util.regex.*; import javax.jmi.reflect.*; import javax.security.auth.callback.*; import javax.security.auth.login.*; import net.sf.farrago.catalog.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.ddl.*; import net.sf.farrago.defimpl.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.fennel.*; import net.sf.farrago.plugin.*; import net.sf.farrago.query.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; import org.eigenbase.jmi.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.resgen.*; import org.eigenbase.resource.*; import org.eigenbase.sql.*; import org.eigenbase.trace.*; import org.eigenbase.util.*; /** * FarragoDbSession implements the {@link net.sf.farrago.session.FarragoSession} * interface as a connection to a {@link FarragoDatabase} instance. It manages * private authorization and transaction context. * *

Most non-trivial public methods on this class must be synchronized, since * closeAllocation may be called from a thread shutting down the database. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSession.java#27 */ public class FarragoDbSession extends FarragoCompoundAllocation implements FarragoSession, Cloneable { //~ Static fields/initializers --------------------------------------------- private static final Logger tracer = FarragoTrace.getDatabaseSessionTracer(); private static final Logger sqlTimingTracer = EigenbaseTrace.getSqlTimingTracer(); public static final String MDR_USER_NAME = "MDR"; //~ Instance fields -------------------------------------------------------- /** * Default personality for this session. */ private FarragoSessionPersonality defaultPersonality; /** * Current personality for this session. */ private FarragoSessionPersonality personality; /** * Fennel transaction context for this session */ private FennelTxnContext fennelTxnContext; /** * Reference to current transaction ID, or null if none active. We do it * this way so that reference is shared across all clones via shallow-copy. */ private TxnIdRef txnIdRef; /** * Qualifiers to assume for unqualified object references */ private FarragoSessionVariables sessionVariables; /** * Database accessed by this session */ private FarragoDatabase database; /** * Repos accessed by this session */ private FarragoRepos repos; /** * URL used to connect this session. */ private String url; /** * Warnings accumulated on this session. */ FarragoWarningQueue warningQueue; /** * Was this session produced by cloning? */ private boolean isClone; private boolean isAutoCommit; private boolean shutDownRequested; private boolean catalogDumpRequested; private boolean shutdownRequested; private boolean reposSessionEnded; private boolean wasKilled; /** * List of savepoints established within current transaction which have not * been released or rolled back; order is from earliest to latest. */ private List savepointList; /** * Generator for savepoint Id's. */ private int nextSavepointId; /** * Map of temporary indexes created by this session. */ private FarragoSessionIndexMap sessionIndexMap; /** * The connection source for this session. */ private FarragoSessionConnectionSource connectionSource; /** * Private cache of executable code pinned by the current txn. */ private Map txnCodeCache; private DatabaseMetaData dbMetaData; protected FarragoSessionFactory sessionFactory; private FarragoSessionPrivilegeMap privilegeMap; private FarragoDbSessionInfo sessionInfo; private Pattern optRuleDescExclusionFilter; private SessionLabel sessionLabel; private boolean isLoopback; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoDbSession object. * * @param url URL used to connect (same as JDBC) * @param info properties for this session * @param sessionFactory factory which created this session */ public FarragoDbSession( String url, Properties info, FarragoSessionFactory sessionFactory) { this.sessionFactory = sessionFactory; this.url = url; warningQueue = new FarragoWarningQueue(); txnIdRef = new TxnIdRef(); sessionLabel = null; boolean requireExistingEngine = info.getProperty( "requireExistingEngine", "false").equalsIgnoreCase("true"); database = FarragoDbSingleton.pinReference( sessionFactory, requireExistingEngine); FarragoDbSingleton.addSession(database, this); boolean success = false; try { init(info); success = true; } finally { if (!success) { closeAllocation(); } } } //~ Methods ---------------------------------------------------------------- private void init(Properties info) { sessionVariables = new FarragoSessionVariables(); String sessionUser = info.getProperty("user", "GUEST"); sessionVariables.sessionUserName = sessionUser; sessionVariables.currentUserName = sessionUser; sessionVariables.currentRoleName = ""; sessionVariables.systemUserName = info.getProperty( "clientUserName", System.getProperty("user.name")); sessionVariables.systemUserFullName = info.getProperty( "clientUserFullName"); sessionVariables.schemaSearchPath = Collections.emptyList(); sessionVariables.sessionName = info.getProperty("sessionName"); sessionVariables.programName = info.getProperty("clientProgramName"); sessionVariables.processId = 0L; String processStr = info.getProperty("clientProcessId"); if ((processStr != null) && (processStr.length() > 0)) { try { sessionVariables.processId = Long.parseLong(processStr); } catch (NumberFormatException ex) { // NOTE jvs 12-Nov-2006: It's OK to discard ex here // because it provides only useless information. getWarningQueue().postWarning( FarragoResource.instance().SessionClientProcessIdNotNumeric .ex(processStr)); } } String remoteProtocol = info.getProperty("remoteProtocol", "none"); FemUser femUser = null; final boolean reentrantMdrSession; if (MDR_USER_NAME.equals(sessionVariables.sessionUserName)) { // This is a reentrant session from MDR. repos = database.getSystemRepos(); reentrantMdrSession = true; } else { repos = database.getUserRepos(); reentrantMdrSession = false; } FarragoReposTxnContext txn = repos.newTxnContext(true); txn.beginReadTxn(); try { if (reentrantMdrSession) { if (sessionVariables.sessionName == null) { sessionVariables.sessionName = MDR_USER_NAME; } } else { // This is a normal session. // Security best practices for failed login attempts: // * report only that username/password combination is invalid // * use same error for "no such user" and "wrong password" // * do not reveal that username exists but password wrong femUser = FarragoCatalogUtil.getUserByName(repos, sessionUser); if (femUser == null) { throw FarragoResource.instance().SessionLoginFailed.ex( repos.getLocalizedObjectName(sessionUser)); } else if ( database.isAuthenticationEnabled() && (database.isAuthenticateLocalConnections() || !remoteProtocol.equals("none"))) { // authenticate; use same SessionLoginFailed if fails LoginContext lc; CallbackHandler cbh = new FarragoNoninteractiveCallbackHandler( info.getProperty("user", "GUEST"), info.getProperty("password")); try { lc = new LoginContext( "Farrago", null, cbh, database.getAuthenticationConfig()); lc.login(); } catch (LoginException ex) { throw FarragoResource.instance().SessionLoginFailed.ex( repos.getLocalizedObjectName(sessionUser)); } try { lc.logout(); } catch (LoginException ex) { throw FarragoResource.instance().SessionLogoutFailed.ex( repos.getLocalizedObjectName(sessionUser)); } } } fennelTxnContext = sessionFactory.newFennelTxnContext( repos, database.getFennelDbHandle()); CwmNamespace defaultNamespace = null; if (femUser != null) { defaultNamespace = femUser.getDefaultNamespace(); } if (defaultNamespace == null) { sessionVariables.catalogName = repos.getSelfAsCatalog().getName(); } else if (defaultNamespace instanceof CwmCatalog) { sessionVariables.catalogName = defaultNamespace.getName(); } else { sessionVariables.schemaName = defaultNamespace.getName(); sessionVariables.catalogName = defaultNamespace.getNamespace().getName(); } } finally { txn.commit(); } txnCodeCache = new HashMap(); isAutoCommit = true; savepointList = new ArrayList(); sessionIndexMap = new FarragoDbSessionIndexMap(this, this, repos); personality = sessionFactory.newSessionPersonality(this, null); defaultPersonality = personality; personality.loadDefaultSessionVariables(sessionVariables); // If a session label has been specified, make sure the personality // supports snapshot reads and the label is valid String labelName = info.getProperty("label", null); if (labelName != null) { if (!getPersonality().supportsFeature( EigenbaseResource.instance().PersonalitySupportsSnapshots)) { throw EigenbaseResource.instance().PersonalitySupportsSnapshots .ex(); } txn.beginReadTxn(); try { FemLabel label = (FemLabel) FarragoCatalogUtil.getModelElementByName( repos.allOfType(FemLabel.class), labelName); if (label == null) { throw FarragoResource.instance().InvalidLabelProperty.ex( labelName); } sessionVariables.set( FarragoDefaultSessionPersonality.LABEL, labelName); setSessionLabel(label); } finally { txn.commit(); } } sessionInfo = new FarragoDbSessionInfo(this, database); } // implement FarragoSession public FarragoSessionFactory getSessionFactory() { return sessionFactory; } // implement FarragoSession public FarragoSessionPersonality getPersonality() { return personality; } // implement FarragoSession public void setDatabaseMetaData(DatabaseMetaData dbMetaData) { this.dbMetaData = dbMetaData; } // implement FarragoSession public void setConnectionSource(FarragoSessionConnectionSource source) { this.connectionSource = source; } // implement FarragoSession public DatabaseMetaData getDatabaseMetaData() { return dbMetaData; } // implement FarragoSession public FarragoSessionConnectionSource getConnectionSource() { return connectionSource; } // implement FarragoSession public String getUrl() { return url; } // implement FarragoSession public FarragoPluginClassLoader getPluginClassLoader() { return database.getPluginClassLoader(); } // implement FarragoSession public List getModelExtensions() { return database.getModelExtensions(); } // implement FarragoSession public FarragoSessionInfo getSessionInfo() { return sessionInfo; } // implement FarragoSession public FarragoWarningQueue getWarningQueue() { return warningQueue; } // implement FarragoSession public synchronized FarragoSessionStmtContext newStmtContext( FarragoSessionStmtParamDefFactory paramDefFactory) { return newStmtContext(paramDefFactory, null); } // implement FarragoSession public synchronized FarragoSessionStmtContext newStmtContext( FarragoSessionStmtParamDefFactory paramDefFactory, FarragoSessionStmtContext rootStmtContext) { FarragoDbStmtContext stmtContext = new FarragoDbStmtContext( this, paramDefFactory, database.getDdlLockManager(), rootStmtContext); addAllocation(stmtContext); return stmtContext; } // implement FarragoSession public synchronized FarragoSessionStmtValidator newStmtValidator() { return new FarragoStmtValidator( getRepos(), getDatabase().getFennelDbHandle(), this, getDatabase().getCodeCache(), getDatabase().getDataWrapperCache(), getSessionIndexMap(), getDatabase().getDdlLockManager()); } // implement FarragoSession public synchronized FarragoSessionPrivilegeChecker newPrivilegeChecker() { // Instantiate a new privilege checker return new FarragoDbSessionPrivilegeChecker(this); } // implement FarragoSession public synchronized FarragoSessionPrivilegeMap getPrivilegeMap() { if (privilegeMap == null) { FarragoDbSessionPrivilegeMap newPrivilegeMap = new FarragoDbSessionPrivilegeMap(repos.getModelView()); getPersonality().definePrivileges(newPrivilegeMap); for (FarragoSessionModelExtension ext : getModelExtensions()) { ext.definePrivileges(newPrivilegeMap); } newPrivilegeMap.makeImmutable(); privilegeMap = newPrivilegeMap; } return privilegeMap; } // implement FarragoSession public synchronized FarragoSession cloneSession( FarragoSessionVariables inheritedVariables) { // TODO: keep track of clones and make sure they aren't left hanging // around by the time stmt finishes executing; also, // maybe auto-propagate unretrieved warnings from clones? try { FarragoDbSession clone = (FarragoDbSession) super.clone(); clone.isClone = true; clone.allocations = new LinkedList(); clone.savepointList = new ArrayList(); clone.warningQueue = new FarragoWarningQueue(); if (isTxnInProgress()) { // Calling statement has already started a transaction: // make sure clone doesn't interfere by autocommitting. clone.isAutoCommit = false; } else { // Otherwise, inherit autocommit setting. clone.isAutoCommit = isAutoCommit; } if (inheritedVariables == null) { inheritedVariables = sessionVariables; } clone.sessionVariables = personality.createInheritedSessionVariables(inheritedVariables); return clone; } catch (CloneNotSupportedException ex) { throw Util.newInternal(ex); } } // implement FarragoSession public boolean isClone() { return isClone; } // implement FarragoSession public boolean isClosed() { // NOTE jvs 18-Nov-2008: don't mark this method as // synchronized; see FRG-294 for why. return (database == null); } // implement FarragoSession public synchronized boolean wasKilled() { return isClosed() && wasKilled; } // implement FarragoSession public boolean isTxnInProgress() { // NOTE jvs 18-Nov-2008: don't mark this method as // synchronized; see FRG-294 for why. // TODO jvs 9-Mar-2006: Unify txn state. if (txnIdRef.txnId != null) { return true; } FennelTxnContext contextToCheck = fennelTxnContext; if (contextToCheck == null) { return false; } return contextToCheck.isTxnInProgress(); } // implement FarragoSession public synchronized FarragoSessionTxnId getTxnId(boolean createIfNeeded) { if ((txnIdRef.txnId == null) && createIfNeeded) { txnIdRef.txnId = getTxnMgr().beginTxn(this); } return txnIdRef.txnId; } // implement FarragoSession public FarragoSessionTxnMgr getTxnMgr() { return database.getTxnMgr(); } // implement FarragoSession public synchronized void setAutoCommit(boolean autoCommit) { ResourceDefinition txnFeature = EigenbaseResource.instance().SQLFeature_E151; if (!autoCommit) { if (!personality.supportsFeature(txnFeature)) { throw EigenbaseResource.instance().SQLFeature_E151.ex(); } } commitImpl(); isAutoCommit = autoCommit; } // implement FarragoSession public boolean isAutoCommit() { return isAutoCommit; } // implement FarragoSession public FarragoSessionVariables getSessionVariables() { return sessionVariables; } // implement FarragoSession public synchronized void endTransactionIfAuto(boolean commit) { if (isAutoCommit) { if (commit) { commitImpl(); } else { rollbackImpl(); } } } // implement FarragoSession public FarragoRepos getRepos() { return repos; } // NOTE jvs 16-Jan-2007: Don't make this synchronized, since that // would reverse the synchronization order inside of closeAllocation, // leading to deadlock // implement FarragoSession public void kill() { closeAllocation(); wasKilled = true; } // implement FarragoSession public void cancel() { for (Long id : sessionInfo.getExecutingStmtIds()) { FarragoSessionExecutingStmtInfo info = sessionInfo.getExecutingStmtInfo(id); info.getStmtContext().cancel(); } } // implement FarragoSession public void disableSubqueryReduction() { sessionVariables.set( FarragoDefaultSessionPersonality.REDUCE_NON_CORRELATED_SUBQUERIES, "false"); } // implement FarragoAllocation public void closeAllocation() { if (isClone) { // avoid synchronization for reentrant sessions; the // reverse ordering can cause deadlock: // top-level session close takes FarragoDbSingleton.class lock, // then statement context lock, // while top-level statement execution holds a lock on the // statement context, and then tries to acquire // FarragoDbSingleton.class lock super.closeAllocation(); // The following will unlock any session labels set by the // reentrant session. // NOTE zfong 8/6/08 - In the case of a UDR session, this is // currently a no-op because session labels cannot be set // inside UDR's. setSessionLabel(null); return; } synchronized (FarragoDbSingleton.class) { synchronized (this) { super.closeAllocation(); if (isClosed()) { return; } if (isTxnInProgress()) { if (isAutoCommit) { commitImpl(); } else { // NOTE jvs 10-May-2005: Technically, we're // supposed to throw an invalid state // exception here. However, it's very // unlikely that the caller is going to handle // it properly, so instead we roll back. If // they wanted their changes committed, they // should have said so. rollbackImpl(); } } try { // unlock the session label, if it has been set setSessionLabel(null); FarragoDbSingleton.disconnectSession(this); } finally { database = null; repos = null; } } } } // implement FarragoSession public synchronized void commit() { if (isAutoCommit) { throw FarragoResource.instance().SessionNoCommitInAutocommit.ex(); } commitImpl(); } // implement FarragoSession public synchronized FarragoSessionSavepoint newSavepoint(String name) { if (name != null) { if (findSavepointByName(name, false) != -1) { throw FarragoResource.instance().SessionDupSavepointName.ex( repos.getLocalizedObjectName(name)); } } return newSavepointImpl(name); } // implement FarragoSession public synchronized void releaseSavepoint(FarragoSessionSavepoint savepoint) { int iSavepoint = validateSavepoint(savepoint); releaseSavepoint(iSavepoint); } // implement FarragoSession public synchronized FarragoSessionAnalyzedSql analyzeSql( String sql, RelDataTypeFactory typeFactory, RelDataType paramRowType, boolean optimize) { FarragoSessionAnalyzedSql analyzedSql = getAnalysisBlock(typeFactory); analyzedSql.optimized = optimize; analyzedSql.paramRowType = paramRowType; FarragoSessionExecutableStmt stmt = prepare( null, sql, null, false, analyzedSql); assert (stmt == null); if (typeFactory != null) { // Have to copy types into the caller's factory since // analysis uses a private factory. if (analyzedSql.paramRowType != null) { analyzedSql.paramRowType = typeFactory.copyType( analyzedSql.paramRowType); } if (analyzedSql.resultType != null) { analyzedSql.resultType = typeFactory.copyType( analyzedSql.resultType); } } return analyzedSql; } private void setSessionLabel(FemLabel label) { FarragoDdlLockManager ddlLockManager = getDatabase().getDdlLockManager(); // Unlock the current label if (sessionLabel != null) { ddlLockManager.removeObjectsInUse(this); tracer.info("Session label reset to null"); } // If the label is an alias, determine the base label that the // alias maps to. This will make it possible to reset the alias to // a new base label even though the original base label is still // in-use. if (label == null) { sessionLabel = null; } else { FemLabel parentLabel = label.getParentLabel(); while (parentLabel != null) { label = parentLabel; parentLabel = label.getParentLabel(); } sessionLabel = new SessionLabel( label.getCommitSequenceNumber(), label.getCreationTimestamp()); } if (sessionLabel != null) { // Lock the new label Set mofId = new HashSet(); CwmModelElement refObj = (CwmModelElement) label; mofId.add(refObj.refMofId()); ddlLockManager.addObjectsInUse(this, mofId); tracer.info( "Session label set to \"" + label.getName() + "\""); } } // implement FarragoSession public Long getSessionLabelCsn() { if (sessionLabel == null) { return null; } else { return sessionLabel.getCommitSequenceNumber(); } } // implement FarragoSession public Timestamp getSessionLabelCreationTimestamp() { if (sessionLabel == null) { return null; } else { return Timestamp.valueOf(sessionLabel.getCreationTimestamp()); } } /** * @return true if the session has a label setting and it is not temporarily * disabled */ private boolean isSessionLabelEnabled() { return (sessionLabel != null); } public FarragoSessionAnalyzedSql getAnalysisBlock( RelDataTypeFactory typeFactory) { return new FarragoSessionAnalyzedSql(); } public FarragoDatabase getDatabase() { return database; } public FarragoSessionIndexMap getSessionIndexMap() { return sessionIndexMap; } public synchronized void setSessionIndexMap( FarragoSessionIndexMap sessionIndexMap) { this.sessionIndexMap = sessionIndexMap; } Map getTxnCodeCache() { return txnCodeCache; } FennelTxnContext getFennelTxnContext() { return fennelTxnContext; } void commitImpl() { tracer.info("commit"); if (fennelTxnContext != null) { fennelTxnContext.commit(); } onEndOfTransaction(FarragoSessionTxnEnd.COMMIT); FarragoReposTxnContext txn = repos.newTxnContext(true); txn.beginReadTxn(); try { sessionIndexMap.onCommit(); } finally { txn.commit(); } } void rollbackImpl() { tracer.info("rollback"); if (fennelTxnContext != null) { fennelTxnContext.rollback(); } onEndOfTransaction(FarragoSessionTxnEnd.ROLLBACK); } private void onEndOfTransaction( FarragoSessionTxnEnd eot) { if (txnIdRef.txnId != null) { getTxnMgr().endTxn(txnIdRef.txnId, eot); txnIdRef.txnId = null; } savepointList.clear(); for (FarragoObjectCache.Entry o : txnCodeCache.values()) { // REVIEW jvs 26-Nov-2006: for pinned ExecStreamGraphs // (and maybe other statement-related resources) can // we verify that they are no longer in use? o.closeAllocation(); } txnCodeCache.clear(); } // implement FarragoSession public synchronized void rollback(FarragoSessionSavepoint savepoint) { if (isAutoCommit) { throw FarragoResource.instance().SessionNoRollbackInAutocommit.ex(); } if (savepoint == null) { rollbackImpl(); } else { int iSavepoint = validateSavepoint(savepoint); rollbackToSavepoint(iSavepoint); } } // implement FarragoSession public synchronized Collection executeLurqlQuery( String lurql, Map argMap) { // TODO jvs 24-May-2005: query cache Connection connection = null; try { if (connectionSource != null) { connection = connectionSource.newConnection(); } JmiQueryProcessor queryProcessor = getPersonality().newJmiQueryProcessor("LURQL"); JmiPreparedQuery query = queryProcessor.prepare( getRepos().getModelView(), lurql); return query.execute(connection, argMap); } catch (JmiQueryException ex) { throw FarragoResource.instance().SessionInternalQueryFailed.ex(ex); } finally { Util.squelchConnection(connection); } } // implement FarragoSession public synchronized void setOptRuleDescExclusionFilter( Pattern exclusionFilter) { optRuleDescExclusionFilter = exclusionFilter; } // implement FarragoSession public Pattern getOptRuleDescExclusionFilter() { return optRuleDescExclusionFilter; } protected FarragoSessionRuntimeParams newRuntimeContextParams() { FarragoSessionRuntimeParams params = new FarragoSessionRuntimeParams(); params.session = this; params.repos = getRepos(); params.codeCache = getDatabase().getCodeCache(); params.txnCodeCache = getTxnCodeCache(); params.fennelTxnContext = getFennelTxnContext(); params.indexMap = getSessionIndexMap(); params.sessionVariables = getSessionVariables().cloneVariables(); params.sharedDataWrapperCache = getDatabase().getDataWrapperCache(); params.streamFactoryProvider = personality; return params; } private FarragoSessionSavepoint newSavepointImpl(String name) { if (isAutoCommit) { throw FarragoResource.instance().SessionNoSavepointInAutocommit .ex(); } FennelSvptHandle fennelSvptHandle = fennelTxnContext.newSavepoint(); FarragoDbSavepoint newSavepoint = new FarragoDbSavepoint( nextSavepointId++, name, fennelSvptHandle, this); savepointList.add(newSavepoint); return newSavepoint; } private int validateSavepoint(FarragoSessionSavepoint savepoint) { if (!(savepoint instanceof FarragoDbSavepoint)) { throw FarragoResource.instance().SessionWrongSavepoint.ex( repos.getLocalizedObjectName(savepoint.getName())); } FarragoDbSavepoint dbSavepoint = (FarragoDbSavepoint) savepoint; if (dbSavepoint.session != this) { throw FarragoResource.instance().SessionWrongSavepoint.ex( savepoint.getName()); } int iSavepoint = findSavepoint(dbSavepoint); if (iSavepoint == -1) { if (savepoint.getName() == null) { throw FarragoResource.instance().SessionInvalidSavepointId.ex( savepoint.getId()); } else { throw FarragoResource.instance().SessionInvalidSavepointName.ex( repos.getLocalizedObjectName(savepoint.getName())); } } return iSavepoint; } private int findSavepointByName( String name, boolean throwIfNotFound) { for (int i = 0; i < savepointList.size(); ++i) { FarragoDbSavepoint savepoint = savepointList.get(i); if (name.equals(savepoint.getName())) { return i; } } if (throwIfNotFound) { throw FarragoResource.instance().SessionInvalidSavepointName.ex( name); } return -1; } private int findSavepoint(FarragoDbSavepoint savepoint) { return savepointList.indexOf(savepoint); } private void releaseSavepoint(int iSavepoint) { // TODO: need Fennel support throw Util.needToImplement(null); } private void rollbackToSavepoint(int iSavepoint) { if (isAutoCommit) { throw FarragoResource.instance().SessionNoRollbackInAutocommit.ex(); } FarragoDbSavepoint savepoint = savepointList.get(iSavepoint); if (repos.isFennelEnabled()) { fennelTxnContext.rollbackToSavepoint( savepoint.getFennelSvptHandle()); } // TODO: list truncation util while (savepointList.size() > (iSavepoint + 1)) { savepointList.remove(savepointList.size() - 1); } } protected FarragoSessionExecutableStmt prepare( FarragoDbStmtContextBase stmtContext, String sql, FarragoAllocationOwner owner, boolean isExecDirect, FarragoSessionAnalyzedSql analyzedSql) { tracer.info(sql); EigenbaseTimingTracer timingTracer = new EigenbaseTimingTracer( sqlTimingTracer, "begin prepare"); // The local variable is necessary to insure that the repository // session can be closed if the statement causes a shutdown. final FarragoRepos repos = this.repos; repos.beginReposSession(); reposSessionEnded = false; FarragoReposTxnContext reposTxnContext = new FarragoReposTxnContext( repos, false, getDatabase().isPartiallyRestored()); boolean [] pRollback = { true }; FarragoSessionStmtValidator stmtValidator = newStmtValidator(); if (stmtContext != null) { stmtValidator.setWarningQueue(stmtContext.getWarningQueue()); } stmtValidator.setTimingTracer(timingTracer); // Pass the repos txn context to the statement validator so // the parser can access it and start the appropriate type of // repository transaction (for DDL vs not DDL) stmtValidator.setReposTxnContext(reposTxnContext); FarragoSessionExecutableStmt stmt = null; try { stmt = prepareImpl( sql, owner, isExecDirect, analyzedSql, stmtContext, stmtValidator, reposTxnContext, pRollback); // NOTE jvs 17-Mar-2006: We have to do this here // rather than in FarragoDbStmtContext.finishPrepare // to ensure that's there's no window in between // when we release the catalog lock and lock the objects; // otherwise a DROP might slip in and yank them out // from under us. if ((stmt != null) && (stmtContext != null)) { stmtContext.lockObjectsInUse(stmt); } } finally { if (stmtValidator != null) { stmtValidator.closeAllocation(); } // MDR doesn't allow rollback on read-only txns if (pRollback[0] && !reposTxnContext.isReadTxnInProgress()) { tracer.fine("rolling back DDL"); reposTxnContext.rollback(); } else { reposTxnContext.commit(); } reposTxnContext.unlockAfterTxn(); if (!reposSessionEnded) { repos.endReposSession(); } } timingTracer.traceTime("end prepare"); return stmt; } private FarragoSessionExecutableStmt prepareImpl( String sql, FarragoAllocationOwner owner, boolean isExecDirect, FarragoSessionAnalyzedSql analyzedSql, FarragoDbStmtContextBase stmtContext, FarragoSessionStmtValidator stmtValidator, FarragoReposTxnContext reposTxnContext, boolean [] pRollback) { // REVIEW: May need to disallow some types of prepared DDL. FarragoSessionDdlValidator ddlValidator = personality.newDdlValidator(stmtValidator); FarragoSessionParser parser = stmtValidator.getParser(); boolean expectStatement = true; if ((analyzedSql != null) && (analyzedSql.paramRowType != null)) { expectStatement = false; } Object parsedObj = parser.parseSqlText( stmtValidator, ddlValidator, sql, expectStatement); stmtValidator.getTimingTracer().traceTime("end parse"); if (parsedObj instanceof SqlNode) { SqlNode sqlNode = (SqlNode) parsedObj; pRollback[0] = false; ddlValidator.closeAllocation(); ddlValidator = null; FarragoSessionExecutableStmt stmt = database.prepareStmt( stmtContext, stmtValidator, sqlNode, owner, analyzedSql); if (isExecDirect) { if (stmt.getDynamicParamRowType().getFieldList().size() > 0) { owner.closeAllocation(); throw FarragoResource.instance() .SessionNoExecuteImmediateParameters.ex(sql); } // DML statements are disallowed if a session label is set. // For CALL statements, the contents of the UDP determines // whether the call can be executed. if (stmt.isDml() && (stmt.getTableModOp() != null) && isSessionLabelEnabled()) { owner.closeAllocation(); throw FarragoResource.instance().ReadOnlySession.ex(); } } return stmt; } FarragoSessionDdlStmt ddlStmt = (FarragoSessionDdlStmt) parsedObj; // DDL statements are disallowed if a session label is set. The // exceptions are the SET statements that only impact the current // session. if (isSessionLabelEnabled() && !((ddlStmt instanceof DdlSetContextStmt) || (ddlStmt instanceof DdlSetSessionParamStmt) || (ddlStmt instanceof DdlSetSessionImplementationStmt))) { throw FarragoResource.instance().ReadOnlySession.ex(); } // If !isExecDirect and we don't need to validate on prepare, then // we only need to parse the statement if (!isExecDirect && !stmtValidator.getSession().getSessionVariables().getBoolean( FarragoDefaultSessionPersonality.VALIDATE_DDL_ON_PREPARE)) { if (ddlStmt.requiresCommit()) { commitImpl(); } return null; } if (ddlStmt.runsAsDml()) { markTableInUse(stmtContext, ddlStmt); } validateDdl(ddlValidator, stmtContext, reposTxnContext, ddlStmt); stmtValidator.getTimingTracer().traceTime("end DDL validation"); // Now that we've validated, we shouldn't continue with execution // when !isExecDirect if (!isExecDirect) { if (ddlStmt.requiresCommit()) { commitImpl(); } return null; } executeDdl(ddlValidator, reposTxnContext, ddlStmt); stmtValidator.getTimingTracer().traceTime("end DDL execution"); pRollback[0] = false; return null; } private void validateDdl( FarragoSessionDdlValidator ddlValidator, FarragoDbStmtContextBase stmtContext, FarragoReposTxnContext reposTxnContext, FarragoSessionDdlStmt ddlStmt) { if (ddlStmt.requiresCommit()) { // most DDL causes implicit commit of any pending txn commitImpl(); } tracer.fine("validating DDL"); if (ddlStmt.runsAsDml()) { accessTargetTable(stmtContext, ddlStmt); } if (ddlStmt.requiresCommit()) { // start a Fennel txn to cover any effects on storage fennelTxnContext.initiateTxn(); } boolean rollbackFennel = true; try { ddlValidator.validate(ddlStmt); rollbackFennel = false; } finally { if (rollbackFennel) { rollbackImpl(); } } } /** * Marks the target table for a DDL statement as in-use. This allows us to * subsequently release the MDR repository lock acquired at the start of * query preparation. Marking the table as in-use prevents it from being * dropped while the repository is unlocked. The lock is released in {@link * DdlExecutionVisitor} during the execution of some types of long-running * DdlStmt. * * @param stmtContext context of the DDL statement * @param ddlStmt the DDL statement */ private void markTableInUse( FarragoDbStmtContextBase stmtContext, FarragoSessionDdlStmt ddlStmt) { // Mark the table as in use, then unlock the repository CwmModelElement table = ddlStmt.getModelElement(); stmtContext.lockObjectInUse(table.refMofId()); } /** * Accesses the target table of a DDL statement for write to prevent * concurrent DML on the same table. * * @param stmtContext context of the DDL statement * @param ddlStmt the DDL statement */ private void accessTargetTable( FarragoDbStmtContextBase stmtContext, FarragoSessionDdlStmt ddlStmt) { // Try to lock the target table List names = new ArrayList(3); CwmModelElement table = ddlStmt.getModelElement(); names.add(table.getName()); for ( CwmNamespace ns = table.getNamespace(); ns != null; ns = ns.getNamespace()) { names.add(ns.getName()); } Collections.reverse(names); boolean success = false; try { stmtContext.accessTable( names, TableAccessMap.Mode.READWRITE_ACCESS); success = true; } finally { if (!success) { // Abort the txn that was implicitly started to acquire the // table lock, if we couldn't acquire the lock stmtContext.getSession().endTransactionIfAuto(false); } } } private void executeDdl( FarragoSessionDdlValidator ddlValidator, FarragoReposTxnContext reposTxnContext, FarragoSessionDdlStmt ddlStmt) { tracer.fine("updating storage"); boolean rollbackFennel = true; try { ddlValidator.executeStorage(); ddlStmt.preExecute(); if (ddlStmt instanceof DdlStmt) { ((DdlStmt) ddlStmt).visit( new DdlExecutionVisitor(reposTxnContext, ddlValidator)); } ddlStmt.postExecute(); tracer.fine("committing DDL"); reposTxnContext.commit(); commitImpl(); rollbackFennel = false; ddlStmt.postCommit(ddlValidator); if (shutDownRequested) { repos.endReposSession(); reposSessionEnded = true; closeAllocation(); database.shutdown(); if (catalogDumpRequested) { try { FarragoReposUtil.dumpRepository(); } catch (Exception ex) { throw FarragoResource.instance().CatalogDumpFailed.ex( ex); } } } } finally { shutDownRequested = false; catalogDumpRequested = false; if (rollbackFennel) { rollbackImpl(); } } } /** * Turns on a flag indicating whether a shutdown request has been made. * * @param val whether to set the flag to true or false */ public void setShutdownRequest(boolean val) { shutdownRequested = val; } /** * @return true if a metamodel dump has been requested */ public boolean shutdownRequested() { return shutdownRequested; } // implement FarragoSession public void setLoopback() { isLoopback = true; } // implement FarragoSession public boolean isLoopback() { return isLoopback; } // implement FarragoSession public boolean isReentrantAlterTableRebuild() { return (getSessionIndexMap().getReloadTable() != null) && !isReentrantAlterTableAddColumn(); } // implement FarragoSession public boolean isReentrantAlterTableAddColumn() { return (getSessionIndexMap().getOldTableStructure() != null); } //~ Inner Classes ---------------------------------------------------------- private class DdlExecutionVisitor extends DdlVisitor { private final FarragoReposTxnContext reposTxnContext; private final FarragoSessionDdlValidator ddlValidator; private DdlExecutionVisitor( FarragoReposTxnContext reposTxnContext, FarragoSessionDdlValidator ddlValidator) { this.reposTxnContext = reposTxnContext; this.ddlValidator = ddlValidator; } // implement DdlVisitor public void visit(DdlCommitStmt stmt) { commit(); } // implement DdlVisitor public void visit(DdlRollbackStmt rollbackStmt) { if (rollbackStmt.getSavepointName() == null) { rollback(null); } else { int iSavepoint = findSavepointByName( rollbackStmt.getSavepointName(), true); rollbackToSavepoint(iSavepoint); } } // implement DdlVisitor public void visit(DdlSavepointStmt savepointStmt) { newSavepoint(savepointStmt.getSavepointName()); } // implement DdlVisitor public void visit(DdlReleaseSavepointStmt releaseStmt) { int iSavepoint = findSavepointByName( releaseStmt.getSavepointName(), true); releaseSavepoint(iSavepoint); } // implement DdlVisitor public void visit(DdlSetCatalogStmt stmt) { SqlIdentifier id = stmt.getCatalogName(); sessionVariables.catalogName = id.getSimple(); } // implement DdlVisitor public void visit(DdlSetSchemaStmt stmt) { SqlIdentifier id = stmt.getSchemaName(); if (id.isSimple()) { sessionVariables.schemaName = id.getSimple(); } else { sessionVariables.catalogName = id.names[0]; sessionVariables.schemaName = id.names[1]; } } // implement DdlVisitor public void visit(DdlSetPathStmt stmt) { sessionVariables.schemaSearchPath = Collections.unmodifiableList(stmt.getSchemaList()); } // implement DdlVisitor public void visit(DdlSetSystemParamStmt stmt) { database.updateSystemParameter(stmt); } // implement DdlVisitor public void visit(DdlCheckpointStmt stmt) { database.requestCheckpoint(false, false); } // implement DdlVisitor public void visit(DdlSetSessionImplementationStmt stmt) { personality = stmt.newPersonality( FarragoDbSession.this, defaultPersonality); personality.loadDefaultSessionVariables(sessionVariables); } // implement DdlVisitor public void visit(DdlExtendCatalogStmt stmt) { // record the model extension plugin jar URL outside of the catalog // so that when we reboot it will be available to MDR database.saveBootUrl(stmt.getJarUrl()); shutDownRequested = true; catalogDumpRequested = true; } // implement DdlVisitor public void visit(DdlReplaceCatalogStmt stmt) { shutDownRequested = true; catalogDumpRequested = true; } // implement DdlVisitor public void visit(DdlDeallocateOldStmt stmt) { database.deallocateOld(); } // implement DdlVisitor public void visit(DdlMultipleTransactionStmt stmt) { Util.permAssert( reposTxnContext.isTxnInProgress(), "must be in repos txn"); boolean readOnly = !stmt.completeRequiresWriteTxn(); boolean needRecovery = false; FarragoSession session = ddlValidator.newReentrantSession(); try { stmt.prepForExecuteUnlocked(ddlValidator, session); reposTxnContext.commit(); reposTxnContext.unlockAfterTxn(); needRecovery = true; stmt.executeUnlocked(ddlValidator, session); needRecovery = false; reposTxnContext.beginLockedTxn(readOnly); stmt.completeAfterExecuteUnlocked( ddlValidator, session, true); } finally { if (needRecovery) { reposTxnContext.beginLockedTxn(readOnly); stmt.completeAfterExecuteUnlocked( ddlValidator, session, false); reposTxnContext.commit(); } ddlValidator.releaseReentrantSession(session); } } // implement DdlVisitor public void visit(DdlSetSessionParamStmt stmt) { if (stmt.getParamName().equals( FarragoDefaultSessionPersonality.LABEL)) { setSessionLabel(stmt.getLabelParamValue()); } } } private static class TxnIdRef { FarragoSessionTxnId txnId; } private static class SessionLabel { Long csn; String timestamp; SessionLabel(Long csn, String timestamp) { this.csn = csn; this.timestamp = timestamp; } Long getCommitSequenceNumber() { return csn; } String getCreationTimestamp() { return timestamp; } } } // End FarragoDbSession.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/package.html0000444000175000017500000000112111173714170023224 0ustar drazzibdrazzib Package net.sf.farrago.db Implements the top-level database container together with generic session/statement management.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/db/package.html#8 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbStmtContextBase.java0000444000175000017500000004272711173714170026466 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbStmtContextBase.java#19 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import java.util.logging.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.resgen.*; import org.eigenbase.resource.*; import org.eigenbase.util.*; /** * FarragoDbStmtContextBase provides a partial implementation of {@link * FarragoSessionStmtContext} in terms of {@link FarragoDbSession}. * *

The basic funtionality provided here may be extended to implement * statements in a way specific to extension projects. * *

See individual methods for assistance in determining when they may be * called. * *

Most non-trivial public methods on this class must be synchronized on the * parent session, since closeAllocation may be called from a thread shutting * down the database. The exception is cancel, which must NOT be synchronized, * since it needs to return immediately. (We synchronize on the parent session * to avoid deadlocks from session/stmt vs. stmt/session lock order; see * http://issues.eigenbase.org/browse/LDB-150 for an example.) * * @author Stephan Zuercher */ public abstract class FarragoDbStmtContextBase implements FarragoSessionStmtContext { //~ Static fields/initializers --------------------------------------------- protected static final Logger tracer = FarragoTrace.getDatabaseStatementContextTracer(); //~ Instance fields -------------------------------------------------------- protected final FarragoDbSession session; protected final FarragoSessionStmtParamDefFactory paramDefFactory; /** * Definitions of dynamic parameters. */ protected FarragoSessionStmtParamDef [] dynamicParamDefs; /** * Current dynamic parameter bindings. */ protected Object [] dynamicParamValues; /** * Indicates if dynamic parameter is set Used to validate that all dynamic * parameters have been set */ protected boolean [] dynamicParamValuesSet; protected boolean daemon; protected String sql; private FarragoDdlLockManager ddlLockManager; private FarragoSessionExecutingStmtInfo info = null; private final long stmtCurrentTime; protected final FarragoSessionStmtContext rootStmtContext; /** * The children statement contexts associated with a root statement context. */ protected List childrenStmtContexts; /** * If non-null, the commit sequence number to be used for all transactions * associated with a root context as well as children contexts associated * with that root context. Only used if the personality supports snapshots. */ protected Long snapshotCsn; /** * Indicates whether the csn associated with the first txn initiated from a * root context or one of its children contexts needs to be saved. Only used * if the personality supports snapshots. */ protected boolean saveFirstCsn; protected final CancelFlag cancelFlag; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoDbStmtContextBase object. * * @param session the session creating this statement * @param paramDefFactory dynamic parameter definition factory * @param ddlLockManager ddl object lock manager */ protected FarragoDbStmtContextBase( FarragoDbSession session, FarragoSessionStmtParamDefFactory paramDefFactory, FarragoDdlLockManager ddlLockManager) { this(session, paramDefFactory, ddlLockManager, null); } /** * Creates a new FarragoDbStmtContextBase object. * * @param session the session creating this statement * @param paramDefFactory dynamic parameter definition factory * @param ddlLockManager ddl object lock manager * @param rootStmtContext the root statement context for an internally * prepared statement; for an externally prepared statement, this will be * null */ protected FarragoDbStmtContextBase( FarragoDbSession session, FarragoSessionStmtParamDefFactory paramDefFactory, FarragoDdlLockManager ddlLockManager, FarragoSessionStmtContext rootStmtContext) { this.session = session; this.paramDefFactory = paramDefFactory; this.ddlLockManager = ddlLockManager; this.rootStmtContext = rootStmtContext; this.snapshotCsn = null; this.saveFirstCsn = false; // For the root context, set the current time that will be used // throughout the statement. For non-root contexts, inherit the // time from the root context. Also, keep track of all of the // children contexts associated with a root context. this.childrenStmtContexts = new ArrayList(); if (rootStmtContext == null) { this.stmtCurrentTime = System.currentTimeMillis(); } else { this.stmtCurrentTime = rootStmtContext.getStmtCurrentTime(); rootStmtContext.addChildStmtContext(this); } cancelFlag = new CancelFlag(); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtContext public void closeAllocation() { synchronized (session) { unprepare(); // purge self from session's list session.forgetAllocation(this); } } // implement FarragoSessionStmtContext public FarragoSession getSession() { return session; } // implement FarragoSessionStmtContext public FarragoSessionExecutingStmtInfo getExecutingStmtInfo() { return info; } // implement FarragoSessionStmtContext public void daemonize() { daemon = true; } // implement FarragoSessionStmtContext public void unprepare() { cancelFlag.clearCancel(); synchronized (session) { sql = null; dynamicParamValues = null; dynamicParamValuesSet = null; ddlLockManager.removeObjectsInUse(this); } } // implement FarragoSessionStmtContext public void setDynamicParam( int parameterIndex, Object x) { synchronized (session) { assert (isPrepared()); Object y = dynamicParamDefs[parameterIndex].scrubValue(x); dynamicParamValues[parameterIndex] = y; dynamicParamValuesSet[parameterIndex] = true; } } // implement FarragoSessionStmtContext public void setDynamicParam( int parameterIndex, Object x, Calendar cal) { synchronized (session) { assert (isPrepared()); Object y = dynamicParamDefs[parameterIndex].scrubValue(x, cal); dynamicParamValues[parameterIndex] = y; dynamicParamValuesSet[parameterIndex] = true; } } // implement FarragoSessionStmtContext public void clearParameters() { synchronized (session) { assert (isPrepared()); Arrays.fill(dynamicParamValuesSet, false); Arrays.fill(dynamicParamValues, null); } } // implement FarragoSessionStmtContext public String getSql() { return sql; } // implement FarragoSessionStmtContext public long getStmtCurrentTime() { return stmtCurrentTime; } // implement FarragoSessionStmtContext public void setSaveFirstTxnCsn() { assert (rootStmtContext == null); if (session.getPersonality().supportsFeature( EigenbaseResource.instance().PersonalitySupportsSnapshots)) { saveFirstCsn = true; } } // implement FarragoSessionStmtContext public boolean needToSaveFirstTxnCsn() { assert (rootStmtContext == null); return saveFirstCsn; } // implement FarragoSessionStmtContext public void saveFirstTxnCsn(long csn) { assert (rootStmtContext == null); // Only the very first csn needs to be saved; so if one is already // set, don't overwrite it. Also, only do this if the personality // supports snapshots. if ((snapshotCsn == null) && session.getPersonality().supportsFeature( EigenbaseResource.instance().PersonalitySupportsSnapshots)) { snapshotCsn = new Long(csn); } } // implement FarragoSessionStmtContext public void addChildStmtContext(FarragoSessionStmtContext childStmtContext) { assert (rootStmtContext == null); childrenStmtContexts.add(childStmtContext); } /** * Starts an auto commit transaction. * *

Call near the beginning of {@link * FarragoSessionStmtContext#execute()}. * * @param readOnly true if statement is read only (e.g. not DML) */ protected void startAutocommitTxn(boolean readOnly) { if (session.isTxnInProgress()) { ResourceDefinition stmtFeature = EigenbaseResource.instance() .SQLConformance_MultipleActiveAutocommitStatements; if (!session.getPersonality().supportsFeature(stmtFeature)) { throw EigenbaseResource.instance() .SQLConformance_MultipleActiveAutocommitStatements.ex(); } } else { Long sessionLabelCsn = session.getSessionLabelCsn(); if (sessionLabelCsn != null) { session.getFennelTxnContext().initiateTxnWithCsn( sessionLabelCsn.longValue()); } else if (snapshotCsn != null) { session.getFennelTxnContext().initiateTxnWithCsn( snapshotCsn.longValue()); } else if (readOnly) { session.getFennelTxnContext().initiateReadOnlyTxn(); } } } /** * Initializes the {@link #dynamicParamDefs} and {@link #dynamicParamValues} * arrays based on the dynamic param row type, * *

Call after statement preparation, when the dynamic param row type is * known, but before {@link FarragoSessionStmtContext#setDynamicParam(int, * Object)} or {@link FarragoSessionStmtContext#clearParameters()}. * * @param dynamicParamRowType dynamic param row type (e.g., {@link * FarragoSessionExecutableStmt#getDynamicParamRowType()} */ protected void initDynamicParams(final RelDataType dynamicParamRowType) { final RelDataTypeField [] fields = dynamicParamRowType.getFields(); // Allocate an array to hold parameter values. dynamicParamValues = new Object[fields.length]; dynamicParamValuesSet = new boolean[fields.length]; // Allocate an array of validators, one for each parameter. dynamicParamDefs = new FarragoSessionStmtParamDef[fields.length]; for (int i = 0; i < fields.length; i++) { final RelDataTypeField field = fields[i]; dynamicParamDefs[i] = paramDefFactory.newParamDef( field.getName(), field.getType()); } } /** * Checks that all dynamic parameters have been set. */ protected void checkDynamicParamsSet() { if (dynamicParamValuesSet != null) { for (int i = 0; i < dynamicParamValuesSet.length; i++) { if (!dynamicParamValuesSet[i]) { throw FarragoResource.instance().ParameterNotSet.ex( Integer.toString(i + 1)); } } } } /** * Acquires locks (or whatever transaction manager wants) on all tables * accessed by this statement. * *

Call during {@link FarragoSessionStmtContext#execute()} to lock tables * used by your {@link FarragoSessionExecutableStmt}. * * @param executableStmt executable statement */ protected void accessTables(FarragoSessionExecutableStmt executableStmt) { TableAccessMap accessMap = executableStmt.getTableAccessMap(); lockTables(accessMap); } /** * Acquires locks (or whatever transaction manager wants) on a single table. * * @param table fully qualified table name, represented as a list * @param mode access mode for the table */ protected void accessTable(List table, TableAccessMap.Mode mode) { TableAccessMap accessMap = new TableAccessMap(table, mode); lockTables(accessMap); } /** * Calls the transaction manager to access a set of tables. * * @param accessMap map containing the tables being accessed and their * access modes */ private void lockTables(TableAccessMap accessMap) { FarragoSessionTxnMgr txnMgr = session.getDatabase().getTxnMgr(); FarragoSessionTxnId txnId = session.getTxnId(true); // If we're attempting to access a table, and the system has only // been partially restored, then raise an exception. if (!accessMap.getTablesAccessed().isEmpty() && session.getDatabase().isPartiallyRestored()) { throw FarragoResource.instance().PartialRestore.ex(); } txnMgr.accessTables( txnId, accessMap); } /** * See FarragoDbSession. * *

Call from {@link FarragoSessionStmtContext#prepare(RelNode, SqlKind, * boolean, FarragoSessionPreparingStmt)} after preparation is complete. * * @param newExecutableStmt */ protected void lockObjectsInUse( FarragoSessionExecutableStmt newExecutableStmt) { // TODO jvs 17-Mar-2006: as a sanity check, verify at the // beginning of each execution that all objects still exist // (to make sure that a DROP didn't sneak in somehow) ddlLockManager.addObjectsInUse( this, newExecutableStmt.getReferencedObjectIds()); } /** * Marks a single object, represented by its mofId, as in-use. * * @param mofId mofId of the object being marked as in-use */ protected void lockObjectInUse(String mofId) { Set mofIds = new HashSet(); mofIds.add(mofId); ddlLockManager.addObjectsInUse(this, mofIds); } /** * Initializes the session's {@link FarragoSessionExecutingStmtInfo}. * *

Call before {@link FarragoSessionExecutableStmt#execute( * FarragoSessionRuntimeContext)}. * * @param executableStmt executable statement */ protected void initExecutingStmtInfo( FarragoSessionExecutableStmt executableStmt) { Set objectsInUse = executableStmt.getReferencedObjectIds(); info = new FarragoDbSessionExecutingStmtInfo( this, session.getDatabase(), sql, Arrays.asList(dynamicParamValues), Arrays.asList( objectsInUse.toArray(new String[objectsInUse.size()]))); FarragoDbSessionInfo sessionInfo = (FarragoDbSessionInfo) session.getSessionInfo(); sessionInfo.addExecutingStmtInfo(info); } /** * Clears session's {@link FarragoSessionExecutingStmtInfo}. * *

Call on {@link FarragoSessionStmtContext#cancel()}, {@link * FarragoSessionStmtContext#closeResultSet()}, or whenever the statement is * known to have stopped executing. */ protected void clearExecutingStmtInfo() { cancelFlag.clearCancel(); if (info == null) { return; } long key = info.getId(); getSessionInfo().removeExecutingStmtInfo(key); info = null; } // implement FarragoSessionStmtContext public CancelFlag getCancelFlag() { return cancelFlag; } /** * Traces execution. * *

Optionally, call from {@link FarragoSessionStmtContext#execute()}. */ protected void traceExecute() { if (!tracer.isLoggable(Level.FINE)) { return; } tracer.fine(sql); if (!tracer.isLoggable(Level.FINER)) { return; } for (int i = 0; i < dynamicParamValues.length; ++i) { tracer.finer("?" + (i + 1) + " = [" + dynamicParamValues[i] + "]"); } } private FarragoDbSessionInfo getSessionInfo() { return (FarragoDbSessionInfo) session.getSessionInfo(); } } // End FarragoDbStmtContextBase.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDatabase.java0000444000175000017500000013604711173714170024634 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDatabase.java#87 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import com.sun.security.auth.login.*; import java.io.*; import java.net.*; import java.util.*; import java.util.concurrent.atomic.*; import java.util.logging.*; import javax.jmi.reflect.*; import javax.security.auth.login.*; import net.sf.farrago.catalog.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.ddl.*; import net.sf.farrago.defimpl.*; import net.sf.farrago.fem.config.*; 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.ojrex.*; import net.sf.farrago.plugin.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.eigenbase.oj.rex.*; import org.eigenbase.rel.*; import org.eigenbase.reltype.*; import org.eigenbase.resource.*; import org.eigenbase.sql.*; import org.eigenbase.sql.fun.*; import org.eigenbase.sql.validate.*; import org.eigenbase.trace.*; import org.eigenbase.util.*; import org.eigenbase.util.property.*; /** * FarragoDatabase is a top-level singleton representing an instance of a * Farrago database engine. * *

NOTE jvs 14-Dec-2005: FarragoDatabase inherits from FarragoDbSingleton for * backwards compatibility. This tie may eventually be severed so that multiple * instances of FarragoDatabase can be created in the same JVM. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDatabase.java#87 $ */ public class FarragoDatabase extends FarragoDbSingleton { //~ Instance fields -------------------------------------------------------- private FarragoRepos systemRepos; private FarragoRepos userRepos; private FennelDbHandle fennelDbHandle; private OJRexImplementorTable ojRexImplementorTable; protected FarragoSessionFactory sessionFactory; private FarragoPluginClassLoader pluginClassLoader; private List modelExtensions; private FarragoDdlLockManager ddlLockManager; private FarragoSessionTxnMgr txnMgr; private Configuration authenticationConfig; private boolean authenticateLocalConnections = false; /** * Set to true if the system has only been partially restored, in which * case, no tables can be accessed and no objects can be created. */ private boolean partialRestore = false; /** * Cache of all sorts of stuff; see the design docs. */ private FarragoObjectCache codeCache; /** * File containing trace configuration. */ private File traceConfigFile; /** * Provides unique identifiers for sessions and statements. */ private AtomicLong uniqueId = new AtomicLong(1); //~ Constructors ----------------------------------------------------------- /** * Creates a FarragoDatabase. * * @param sessionFactory factory for various database-level objects * @param init whether to initialize the system catalog (the first time the * database is started) */ public FarragoDatabase( FarragoSessionFactory sessionFactory, boolean init) { if (instance == null) { instance = this; } try { FarragoCompoundAllocation startOfWorldAllocation = new FarragoCompoundAllocation(); this.addAllocation(startOfWorldAllocation); StringProperty prop = FarragoProperties.instance().traceConfigFile; String loggingConfigFile = prop.get(); if (loggingConfigFile == null) { throw FarragoResource.instance().MissingHomeProperty.ex( prop.getPath()); } traceConfigFile = new File(loggingConfigFile); dumpTraceConfig(); this.sessionFactory = sessionFactory; // Tell MDR about our plugin ClassLoader so that it can find // extension model JMI interfaces in plugin jars. pluginClassLoader = new FarragoPluginClassLoader(); MDRepositoryFactory.setClassLoaderProvider( new ClassLoaderProvider() { public ClassLoader getClassLoader() { return pluginClassLoader; } public Class defineClass( String className, byte [] classfile) { return null; } }); // Load all model plugin URL's early so that MDR won't try to // generate its own bytecode for JMI interfaces. loadBootUrls(); systemRepos = sessionFactory.newRepos(this, false); systemRepos.beginReposSession(); try { userRepos = systemRepos; if (init) { FarragoCatalogInit.createSystemObjects(systemRepos); } // REVIEW: system/user configuration FemFarragoConfig currentConfig = systemRepos.getCurrentConfig(); tracer.config( "java.class.path = " + System.getProperty("java.class.path")); tracer.config( "java.library.path = " + System.getProperty("java.library.path")); // NOTE jvs 8-Dec-2008: a pure-Java DBMS based on Farrago // would need some non-Fennel mechanism for detecting that // catalog recovery is needed. if (systemRepos.isFennelEnabled()) { FarragoReposTxnContext txn = systemRepos.newTxnContext(); try { txn.beginWriteTxn(); boolean recoveryRequired = loadFennel( startOfWorldAllocation, sessionFactory.newFennelCmdExecutor(), init); // This updateCatalog step always needs to run to deal // with the case of starting up after a restore (in // which case recoveryRequired=false). updateCatalog(recoveryRequired); txn.commit(); } finally { txn.rollback(); } } else { tracer.config("Fennel support disabled"); } long codeCacheMaxBytes = getCodeCacheMaxBytes(currentConfig); codeCache = new FarragoObjectCache( this, codeCacheMaxBytes, new FarragoLruVictimPolicy()); ojRexImplementorTable = new FarragoOJRexImplementorTable( SqlStdOperatorTable.instance()); // Create instances of plugin model extensions for shared use // by all sessions. loadModelPlugins(); // REVIEW: sequencing from this point on if (currentConfig.isUserCatalogEnabled()) { userRepos = sessionFactory.newRepos(this, true); if (userRepos.getSelfAsCatalog() == null) { // REVIEW: request this explicitly? FarragoCatalogInit.createSystemObjects(userRepos); } // During shutdown, we want to reverse this process, making // userRepos revert to systemRepos. ReposSwitcher takes // care of this before userRepos gets closed. addAllocation(new ReposSwitcher()); } // Start up timer. This comes last so that the first thing we // do in close is to cancel it, avoiding races with other // shutdown activity. Timer timer = new Timer("Farrago Watchdog Timer"); new FarragoTimerAllocation(this, timer); timer.schedule(new WatchdogTask(), 1000, 1000); if (currentConfig.getCheckpointInterval() > 0) { long checkpointIntervalMillis = currentConfig.getCheckpointInterval(); checkpointIntervalMillis *= 1000; timer.schedule( new CheckpointTask(), checkpointIntervalMillis, checkpointIntervalMillis); } ddlLockManager = new FarragoDdlLockManager(); txnMgr = sessionFactory.newTxnMgr(); sessionFactory.specializedInitialization(this); File jaasConfigFile = new File( FarragoProperties.instance().homeDir.get(), "plugin/jaas.config"); if (jaasConfigFile.exists()) { System.setProperty( "java.security.auth.login.config", jaasConfigFile.getPath()); authenticationConfig = new ConfigFile(); } } finally { systemRepos.endReposSession(); } } catch (Throwable ex) { tracer.throwing("FarragoDatabase", "", ex); close(true); throw FarragoResource.instance().DatabaseLoadFailed.ex(ex); } } //~ Methods ---------------------------------------------------------------- /** * @return the shared code cache for this database */ public FarragoObjectCache getCodeCache() { return codeCache; } /** * Flushes unpinned entries from the cache cache for this database. */ public void flushCodeCache() { // REVIEW: SWZ 2008-09-15: Seems to me that this (and other changes // to code cache size) should be synchronized. // Flush code cache in an attempt to close loopback sessions. long maxBytes = codeCache.getBytesMax(); codeCache.setMaxBytes(0); codeCache.setMaxBytes(maxBytes); } /** * @return the shared data wrapper cache for this database */ public FarragoObjectCache getDataWrapperCache() { // data wrapper caching is actually unified with the code cache return codeCache; } /** * @return ClassLoader for loading plugins */ public FarragoPluginClassLoader getPluginClassLoader() { return pluginClassLoader; } /** * @return list of installed {@link FarragoSessionModelExtension} instances */ public List getModelExtensions() { return modelExtensions; } /** * @return transaction manager for this database */ public FarragoSessionTxnMgr getTxnMgr() { return txnMgr; } /** * Sets the transaction manager for this database. This is intended only for * use by white-box tests; it should not be called otherwise. * * @param txnMgr new transaction manager */ public void setTxnMgr(FarragoSessionTxnMgr txnMgr) { this.txnMgr = txnMgr; } private File getBootUrlFile() { return new File( FarragoProperties.instance().getCatalogDir(), "FarragoBootUrls.lst"); } private void loadBootUrls() { FileReader fileReader; try { fileReader = new FileReader(getBootUrlFile()); } catch (FileNotFoundException ex) { // if file doesn't exist, it's safe to assume that there // are no model plugins yet return; } LineNumberReader lineReader = new LineNumberReader(fileReader); try { for (;;) { String line = lineReader.readLine(); if (line == null) { break; } URL url = new URL( FarragoProperties.instance().expandProperties(line)); pluginClassLoader.addPluginUrl(url); } } catch (Throwable ex) { throw FarragoResource.instance().CatalogBootUrlReadFailed.ex(ex); } } void saveBootUrl(String url) { // append FileWriter fileWriter = null; try { fileWriter = new FileWriter( getBootUrlFile(), true); PrintWriter pw = new PrintWriter(fileWriter); pw.println(url); pw.close(); fileWriter.close(); } catch (Throwable ex) { throw FarragoResource.instance().CatalogBootUrlUpdateFailed.ex(ex); } finally { Util.squelchWriter(fileWriter); } } private void loadModelPlugins() { List resourceBundles = new ArrayList(); sessionFactory.defineResourceBundles(resourceBundles); modelExtensions = new ArrayList(); Collection allJars = systemRepos.allOfClass(FemJar.class); for (FemJar jar : allJars) { if (jar.isModelExtension()) { FarragoSessionModelExtension modelExtension = sessionFactory.newModelExtension( pluginClassLoader, jar); modelExtensions.add(modelExtension); modelExtension.defineResourceBundles(resourceBundles); } } // add repository localization for model extensions systemRepos.addResourceBundles(resourceBundles); } public void close(boolean suppressExcns) { try { // This will close (in reverse order) all the FarragoAllocations // opened by the constructor. synchronized (this) { closeAllocation(); } assertNoFennelHandles(); } catch (Throwable ex) { warnOnClose(ex, suppressExcns); } fennelDbHandle = null; systemRepos = null; userRepos = null; } private void warnOnClose( Throwable ex, boolean suppressExcns) { tracer.warning( "Caught " + ex.getClass().getName() + " during database shutdown:" + ex.getMessage()); if (!suppressExcns) { tracer.log(Level.SEVERE, "warnOnClose", ex); tracer.throwing("FarragoDatabase", "warnOnClose", ex); throw Util.newInternal(ex); } } private void dumpTraceConfig() { try { FileReader fileReader = new FileReader(traceConfigFile); StringWriter stringWriter = new StringWriter(); FarragoUtil.copyFromReaderToWriter(fileReader, stringWriter); tracer.config(stringWriter.toString()); } catch (IOException ex) { tracer.severe( "Caught IOException while dumping trace configuration: " + ex.getMessage()); } } private void assertNoFennelHandles() { assert systemRepos != null : "FarragoDatabase.systemRepos is " + "null: server has probably already been started"; if (!systemRepos.isFennelEnabled()) { return; } int n = FennelStorage.getHandleCount(); assert (n == 0) : "FennelStorage.getHandleCount() == " + n; } private boolean loadFennel( FarragoCompoundAllocation startOfWorldAllocation, FennelCmdExecutor cmdExecutor, boolean init) throws Exception { tracer.fine("Loading Fennel"); assertNoFennelHandles(); FemCmdOpenDatabase cmd = systemRepos.newFemCmdOpenDatabase(); FemFennelConfig fennelConfig = systemRepos.getCurrentConfig().getFennelConfig(); SortedMap configMap = JmiObjUtil.getAttributeValues(fennelConfig); filterMapNullValues(configMap); // Copy config into a properties object, then tell the session mgr // about them. Note that some of the properties may be non-Strings. Properties properties = new Properties(); properties.putAll(configMap); sessionFactory.applyFennelExtensionParameters(properties); // The applyFennelExtensionParameters method may have modified the // properties, so copy them back. for ( Map.Entry entry : Util.toMap(properties).entrySet()) { configMap.put(entry.getKey(), entry.getValue()); } for (Map.Entry entry : configMap.entrySet()) { String expandedValue = FarragoProperties.instance().expandProperties( entry.getValue().toString()); FemDatabaseParam param = systemRepos.newFemDatabaseParam(); param.setName(entry.getKey()); param.setValue(expandedValue); cmd.getParams().add(param); } // databaseDir is set dynamically, allowing the catalog // to be moved FemDatabaseParam param1 = systemRepos.newFemDatabaseParam(); param1.setName("databaseDir"); param1.setValue( FarragoProperties.instance().getCatalogDir().getAbsolutePath()); cmd.getParams().add(param1); for (FemDatabaseParam param : cmd.getParams()) { // REVIEW: use Fennel tracer instead? tracer.config( "Fennel parameter " + param.getName() + "=" + param.getValue()); } cmd.setCreateDatabase(init); NativeTrace.createInstance("net.sf.fennel."); fennelDbHandle = new FennelDbHandleImpl(systemRepos, this, cmdExecutor, cmd); tracer.config("Fennel successfully loaded"); return cmd.isResultRecoveryRequired(); } /** * Updates the catalog on startup, taking care of any cleanup or recovery. * * @param recoveryRequired true if starting up after a crash */ private void updateCatalog(boolean recoveryRequired) throws Exception { // TODO jvs 14-Oct-2008: give extension models a chance // to clean up their portions of the catalog. cleanupBackupData(!recoveryRequired, false); // No repos transaction needed since we're already inside one. List refs = new ArrayList( systemRepos.getMedPackage().getFemRecoveryReference() .refAllOfType()); // NOTE jvs 9-Dec-2008: even when recoveryRequired=false, // refs may be non-empty, since we may be restoring from // a hot backup which was started while an operation such // as ALTER TABLE ADD COLUMN was already in progress. for (FemRecoveryReference ref : refs) { // TODO jvs 8-Dec-2008: proper dispatch mechanism // once we have more of these; for now there's only one assert (ref.getRecoveryType() == RecoveryTypeEnum.ALTER_TABLE_ADD_COLUMN); CwmDependency dep = ref.getClientDependency().iterator().next(); CwmModelElement element = dep.getSupplier().iterator().next(); assert (element instanceof CwmTable); DdlAlterTableStructureStmt.recover( systemRepos, (CwmTable) element); ref.refDelete(); } } /** * Simulates the catalog recovery which would occur on startup after a * crash. This allows tests to set up a crash representation in the catalog * and then invoke recovery without actually having to bring down the JVM. */ public void simulateCatalogRecovery() throws Exception { FarragoReposTxnContext txn = systemRepos.newTxnContext(); try { txn.beginWriteTxn(); updateCatalog(true); txn.commit(); } finally { txn.rollback(); } } /** * Cleans up the system backup catalog by either removing pending backup * data if the last backup failed, or by updating the pending data to * completed, if the last backup succeeded. * * @param backupSucceeded whether the last backup was successful * @param setEndTimestamp if true, record the current timestamp as the * ending timestamp when updating pending data to completed */ public void cleanupBackupData( boolean backupSucceeded, boolean setEndTimestamp) throws Exception { FarragoReposTxnContext reposTxnContext = new FarragoReposTxnContext(systemRepos, true); try { reposTxnContext.beginWriteTxn(); partialRestore = FarragoCatalogUtil.updatePendingBackupData( systemRepos, backupSucceeded, setEndTimestamp); reposTxnContext.commit(); } finally { reposTxnContext.rollback(); } } /** * Determines if the database is in a state where a partial restore has * been done, which indicates that the catalog data is not in sync with * table data. Therefore, any attempt to access a table or create/modify * an object should result in an error. * * @return true if the database is in a partial restore state */ public boolean isPartiallyRestored() { return partialRestore; } private void filterMapNullValues(Map configMap) { Iterator> configMapIter = configMap.entrySet().iterator(); while (configMapIter.hasNext()) { Map.Entry entry = configMapIter.next(); if (entry.getValue() == null) { configMapIter.remove(); } } } /** * @return shared OpenJava implementation table for SQL operators */ public OJRexImplementorTable getOJRexImplementorTable() { return ojRexImplementorTable; } /** * @return system repos for this database */ public FarragoRepos getSystemRepos() { return systemRepos; } /** * @return user repos for this database */ public FarragoRepos getUserRepos() { return userRepos; } /** * @return true if there is a JAAS configuration entry for application * "Farrago". */ public boolean isAuthenticationEnabled() { if (authenticationConfig == null) { return false; } else { return true; } } /** * @return the JAAS authentication configuration. */ public Configuration getAuthenticationConfig() { return authenticationConfig; } /** * @return the Fennel database handle associated with this database */ public FennelDbHandle getFennelDbHandle() { return fennelDbHandle; } /** * Sets the fennel DB handle used by the database. Allows non fennel * implementations to override the handle and substitute your own * implementation */ public void setFennelDbHandle(FennelDbHandle handle) { fennelDbHandle = handle; } /** * @return the DDL lock manager associated with this database */ public FarragoDdlLockManager getDdlLockManager() { return ddlLockManager; } /** * Gets a unique identifier: never 0. * * @return next unique identifier */ public long getUniqueId() { return uniqueId.incrementAndGet(); } // REVIEW mberkowitz 28-Mar-06: Is it better for the FarragoDatabase // to save a map (id -> FarragoSessionInfo) // and a map (id -> FarragoSessionExecutingStmtInfo)? /** * look up session info by session id. * * @param id * * @return FarragoSessionInfo */ public FarragoSessionInfo findSessionInfo(long id) { for (FarragoSession s : getSessions(this)) { FarragoSessionInfo info = s.getSessionInfo(); if (info.getId() == id) { return info; } } return null; } /** * Looks up executing statement info by statement id. * * @param id * * @return FarragoSessionExecutingStmtInfo */ public FarragoSessionExecutingStmtInfo findExecutingStmtInfo(long id) { for (FarragoSession s : getSessions(this)) { FarragoSessionExecutingStmtInfo info = s.getSessionInfo().getExecutingStmtInfo(id); if (info != null) { return info; } } return null; } /** * Kills a session. * * @param id session identifier * @param cancelOnly if true, just cancel current execution; if false, * destroy session */ public void killSession(long id, boolean cancelOnly) throws Throwable { tracer.info("killSession " + id); FarragoSessionInfo info = findSessionInfo(id); if (info == null) { throw FarragoResource.instance().SessionNotFound.ex(id); } FarragoDbSession target = (FarragoDbSession) info.getSession(); if (target.isClosed()) { tracer.info("killSession " + id + ": already closed"); return; } if (cancelOnly) { target.cancel(); } else { target.kill(); } } private void kill(FarragoSessionExecutingStmtInfo info, boolean cancelOnly) throws Throwable { FarragoSessionStmtContext stmt = info.getStmtContext(); if (stmt == null) { Long id = info.getId(); tracer.info("killExecutingStmt " + id + ": statement not found"); throw new Throwable("executing statement not found: " + id); // i18n } if (tracer.isLoggable(Level.INFO)) { tracer.info( "killStatement " + info.getId() + "(session " + stmt.getSession().getSessionInfo().getId() + "), " + stmt.getSql()); } if (cancelOnly) { stmt.cancel(); } else { // LER-7874 - kill comes from another thread, make sure we've // detached that thread's session (if any) so we can attach the // to the running statement's session and end it. EnkiMDRepository mdrRepos = systemRepos.getEnkiMdrRepos(); EnkiMDSession detachedReposSession = mdrRepos.detachSession(); try { stmt.kill(); } finally { mdrRepos.reattachSession( detachedReposSession); } } } /** * Kill an executing statement: cancel it and deallocate it. * * @param id statement id * @param cancelOnly if true, just cancel current execution; if false, * destroy statement */ public void killExecutingStmt(long id, boolean cancelOnly) throws Throwable { tracer.info("killExecutingStmt " + id); FarragoSessionExecutingStmtInfo info = findExecutingStmtInfo(id); if (info == null) { tracer.info("killExecutingStmt " + id + ": statement not found"); throw new Throwable("executing statement not found: " + id); // i18n } kill(info, cancelOnly); } /** * Kills all statements that are executing SQL that matches a given pattern, * but does not match a second pattern. Not an error if none match. * * @param match pattern to match. Null string matches nothing, to be safe. * @param nomatch pattern not to match * @param cancelOnly if true, just cancel current execution; if false, * destroy statement * * @return count of killed statements. */ public int killExecutingStmtMatching( String match, String nomatch, boolean cancelOnly) throws Throwable { int ct = 0; tracer.info( "killExecutingStmtMatching " + match + " but not " + nomatch); // scan all statements if (match.length() > 0) { for (FarragoSession sess : getSessions(this)) { FarragoSessionInfo sessInfo = sess.getSessionInfo(); for (Long id : sessInfo.getExecutingStmtIds()) { FarragoSessionExecutingStmtInfo info = sessInfo.getExecutingStmtInfo(id); if (info.getSql().contains(nomatch)) { continue; } if (info.getSql().contains(match)) { kill(info, cancelOnly); ct++; } } } } tracer.info("killed " + ct + " statements"); return ct; } /** * Prepares an SQL expression; uses a cached implementation if available, * otherwise caches the one generated here. * * @param stmtContext embracing stmt context * @param stmtValidator generic stmt validator * @param sqlNode the parsed form of the statement * @param owner the FarragoAllocationOwner which will be responsible for the * returned stmt * @param analyzedSql receives information about a prepared expression * * @return statement implementation, or null when analyzedSql is non-null */ public FarragoSessionExecutableStmt prepareStmt( FarragoSessionStmtContext stmtContext, FarragoSessionStmtValidator stmtValidator, SqlNode sqlNode, FarragoAllocationOwner owner, FarragoSessionAnalyzedSql analyzedSql) { final FarragoSessionPreparingStmt stmt = stmtValidator.getSession().getPersonality().newPreparingStmt( stmtContext, stmtValidator); return prepareStmtImpl(stmt, sqlNode, owner, analyzedSql); } /** * Implements a logical or physical query plan but does not execute it. * * @param prep the FarragoSessionPreparingStmt that is managing the query. * @param rootRel root of query plan (relational expression) * @param sqlKind SqlKind for the relational expression: only * SqlKind.Explain and SqlKind.Dml are special cases. * @param logical true for a logical query plan (still needs to be * optimized), false for a physical plan. * @param owner the FarragoAllocationOwner which will be responsible for the * returned stmt * * @return statement implementation */ public FarragoSessionExecutableStmt implementStmt( FarragoSessionPreparingStmt prep, RelNode rootRel, SqlKind sqlKind, boolean logical, FarragoAllocationOwner owner) { try { FarragoSessionExecutableStmt executable = prep.implement(rootRel, sqlKind, logical); owner.addAllocation(executable); return executable; } finally { prep.closeAllocation(); } } private FarragoSessionExecutableStmt prepareStmtImpl( final FarragoSessionPreparingStmt stmt, final SqlNode sqlNode, FarragoAllocationOwner owner, FarragoSessionAnalyzedSql analyzedSql) { final EigenbaseTimingTracer timingTracer = stmt.getStmtValidator().getTimingTracer(); final FarragoRepos stmtRepos = stmt.getRepos(); // REVIEW jvs 27-Aug-2005: what are the security implications of // EXPLAIN PLAN? // It would be silly to cache EXPLAIN PLAN results, so deal with them // directly. Also check for whether statement caching is turned off // for the session before continuing. boolean cacheStatements = stmt.getSession().getSessionVariables().getBoolean( FarragoDefaultSessionPersonality.CACHE_STATEMENTS); if (sqlNode.isA(SqlKind.Explain) || (cacheStatements == false)) { FarragoSessionExecutableStmt executableStmt = stmt.prepare(sqlNode, sqlNode); owner.addAllocation(executableStmt); return executableStmt; } // Use unparsed validated SQL as cache key. This eliminates trivial // differences such as whitespace and implicit qualifiers. SqlValidator sqlValidator = stmt.getSqlValidator(); final SqlNode validatedSqlNode; if ((analyzedSql != null) && (analyzedSql.paramRowType != null)) { Map nameToTypeMap = new HashMap(); for ( RelDataTypeField field : analyzedSql.paramRowType.getFieldList()) { nameToTypeMap.put( field.getName(), field.getType()); } validatedSqlNode = sqlValidator.validateParameterizedExpression( sqlNode, nameToTypeMap); } else { validatedSqlNode = sqlValidator.validate(sqlNode); } stmt.postValidate(validatedSqlNode); timingTracer.traceTime("end validation"); SqlDialect sqlDialect = new SqlDialect(stmt.getSession().getDatabaseMetaData()); final String sql = validatedSqlNode.toSqlString(sqlDialect); if (analyzedSql != null) { if (validatedSqlNode instanceof SqlSelect) { // assume we're validating a view SqlSelect select = (SqlSelect) validatedSqlNode; if (select.getOrderList() != null) { analyzedSql.hasTopLevelOrderBy = true; } } // Need to force preparation so we can dig out required info, so // don't use cache. Also, don't need to go all the way with // stmt implementation either; can stop after validation, which // provides needed metadata. (In fact, we CAN'T go much further, // because if a view is being created as part of a CREATE SCHEMA // statement, some of the tables it depends on may not have // storage defined yet.) analyzedSql.canonicalString = sql; stmt.analyzeSql(validatedSqlNode, analyzedSql); timingTracer.traceTime("end analyzeSql"); return null; } String key = sql + ";label="; FarragoDbSession session = (FarragoDbSession) stmt.getSession(); Long labelCsn = session.getSessionLabelCsn(); if (labelCsn != null) { key += labelCsn; } final String stmtKey = key; FarragoObjectCache.Entry cacheEntry; FarragoObjectCache.CachedObjectFactory stmtFactory = new FarragoObjectCache.CachedObjectFactory() { public void initializeEntry( Object key, FarragoObjectCache.UninitializedEntry entry) { timingTracer.traceTime("code cache miss"); assert (key.equals(stmtKey)); FarragoSessionExecutableStmt executableStmt = stmt.prepare(validatedSqlNode, sqlNode); long memUsage = FarragoUtil.getStringMemoryUsage(sql) + executableStmt.getMemoryUsage(); entry.initialize( executableStmt, memUsage, stmt.mayCacheImplementation()); } public boolean isStale(Object value) { FarragoSessionExecutableStmt executableStmt = (FarragoSessionExecutableStmt) value; return isExecutableStmtStale( stmtRepos, executableStmt); } }; // sharing of executable statements depends on session personality; // default for vanilla Farrago personality is that statements // are sharable final boolean sharable = stmt.getSession().getPersonality().supportsFeature( EigenbaseResource.instance().SharedStatementPlans); // prepare the statement, caching the results in codeCache cacheEntry = codeCache.pin(stmtKey, stmtFactory, !sharable); FarragoSessionExecutableStmt executableStmt = (FarragoSessionExecutableStmt) cacheEntry.getValue(); owner.addAllocation(cacheEntry); return executableStmt; } private boolean isExecutableStmtStale( FarragoRepos repos, FarragoSessionExecutableStmt stmt) { for (String mofid : stmt.getReferencedObjectIds()) { RefBaseObject obj = repos.getMdrRepos().getByMofId(mofid); if (obj == null) { // the object was deleted return true; } if (obj instanceof FemAnnotatedElement) { String cachedModTime = stmt.getReferencedObjectModTime(mofid); if (cachedModTime == null) { continue; } FemAnnotatedElement annotated = (FemAnnotatedElement) obj; String lastModTime = annotated.getModificationTimestamp(); if (!cachedModTime.equals(lastModTime)) { // the object was modified return true; } } } return false; } public void updateSystemParameter(DdlSetSystemParamStmt ddlStmt) { // TODO: something cleaner boolean setCodeCacheSize = false; String paramName = ddlStmt.getParamName(); if (paramName.equals("calcVirtualMachine")) { // sanity check if (!userRepos.isFennelEnabled()) { CalcVirtualMachine vm = userRepos.getCurrentConfig().getCalcVirtualMachine(); if (vm.equals(CalcVirtualMachineEnum.CALCVM_FENNEL)) { throw FarragoResource.instance().ValidatorCalcUnavailable .ex(); } } // when this parameter changes, we need to clear the code cache, // since cached plans may be based on the old setting codeCache.setMaxBytes(0); // this makes sure that we reset the cache to the correct size // below setCodeCacheSize = true; } if (paramName.equals("codeCacheMaxBytes")) { setCodeCacheSize = true; } if (setCodeCacheSize) { codeCache.setMaxBytes( getCodeCacheMaxBytes(systemRepos.getCurrentConfig())); } // Prevent negative values. Fennel uses an unsigned 32-bit int for // these parameters and will convert negative values into large // positive values. Prevent this for sanity. (Could switch catalog to // use longs to provide access to the full Fennel range of values.) if (paramName.equals("cachePagesMax") || paramName.equals("cachePagesInit")) { int cachePagesMax = ddlStmt.getParamValue().intValue(false); String upperBound = paramName.equals("cachePagesMax") ? String.valueOf(Integer.MAX_VALUE) : "'cachePagesMax'"; if (cachePagesMax <= 0) { throw FarragoResource.instance().InvalidParam.ex( "1", upperBound); } } if (paramName.equals("prefetchPagesMax")) { int paramVal = ddlStmt.getParamValue().intValue(false); FemFennelConfig config = systemRepos.getCurrentConfig().getFennelConfig(); int cachePages = config.getCachePagesInit(); if ((paramVal < 0) || (paramVal > cachePages)) { throw FarragoResource.instance().InvalidParam.ex( "0", "'cachePagesInit'"); } } if (paramName.equals("prefetchThrottleRate")) { int paramVal = ddlStmt.getParamValue().intValue(false); if (paramVal < 1) { throw FarragoResource.instance().InvalidParam.ex( "1", String.valueOf(Integer.MAX_VALUE)); } } if (paramName.equals("cachePagesInit") || paramName.equals("expectedConcurrentStatements") || paramName.equals("cacheReservePercentage")) { executeFennelSetParam(paramName, ddlStmt.getParamValue()); } } private long getCodeCacheMaxBytes(FemFarragoConfig config) { long codeCacheMaxBytes = config.getCodeCacheMaxBytes(); if (codeCacheMaxBytes == -1) { codeCacheMaxBytes = Long.MAX_VALUE; } return codeCacheMaxBytes; } private void executeFennelSetParam(String paramName, SqlLiteral paramValue) { if (!systemRepos.isFennelEnabled()) { return; } FemCmdSetParam cmd = systemRepos.newFemCmdSetParam(); cmd.setDbHandle(fennelDbHandle.getFemDbHandle(systemRepos)); FemDatabaseParam param = systemRepos.newFemDatabaseParam(); param.setName(paramName); param.setValue(paramValue.toString()); cmd.setParam(param); fennelDbHandle.executeCmd(cmd); } public void requestCheckpoint( boolean fuzzy, boolean async) { if (!systemRepos.isFennelEnabled()) { return; } FemCmdCheckpoint cmd = systemRepos.newFemCmdCheckpoint(); cmd.setDbHandle(fennelDbHandle.getFemDbHandle(systemRepos)); cmd.setFuzzy(fuzzy); cmd.setAsync(async); fennelDbHandle.executeCmd(cmd); } public void deallocateOld() { if (!systemRepos.isFennelEnabled()) { return; } // Find the csn of the oldest label. Since the catalog is locked // for the duration of this statement, it isn't possible for // a CREATE LABEL statement to sneak in and invalidate the result of // this call. Long labelCsn = FarragoCatalogUtil.getOldestLabelCsn(userRepos); FemCmdAlterSystemDeallocate cmd = systemRepos.newFemCmdAlterSystemDeallocate(); cmd.setDbHandle(fennelDbHandle.getFemDbHandle(systemRepos)); if (labelCsn == null) { cmd.setOldestLabelCsn(-1); } else { cmd.setOldestLabelCsn(labelCsn); } fennelDbHandle.executeCmd(cmd); } public static FarragoSessionFactory newSessionFactory() { String libraryName = FarragoProperties.instance().defaultSessionFactoryLibraryName.get(); try { FarragoPluginClassLoader classLoader = new FarragoPluginClassLoader(); Class c = classLoader.loadClassFromLibraryManifest( libraryName, "SessionFactoryClassName"); return (FarragoSessionFactory) classLoader.newPluginInstance(c); } catch (Throwable ex) { throw FarragoResource.instance().PluginInitFailed.ex( libraryName, ex); } } /** * Main entry point which creates a new Farrago database. * * @param args ignored */ public static void main(String [] args) { FarragoDatabase database = new FarragoDatabase( FarragoDatabase.newSessionFactory(), true); database.close(false); } public boolean isAuthenticateLocalConnections() { return authenticateLocalConnections; } /** * Turns on/off authentication for in-process jdbc sessions. NOTE: If set to * off, the origin of the jdbc connection is determined by the * remoteProtocol attribute of the jdbc URL. * * @param authenticateLocalConnections */ public void setAuthenticateLocalConnections( boolean authenticateLocalConnections) { this.authenticateLocalConnections = authenticateLocalConnections; } //~ Inner Classes ---------------------------------------------------------- /** * 1 Hz task for background activities. Currently all it does is re-read the * trace configuration file whenever it changes. */ private class WatchdogTask extends FarragoTimerTask { private long prevTraceConfigTimestamp; WatchdogTask() { super(tracer); prevTraceConfigTimestamp = traceConfigFile.lastModified(); } // implement FarragoTimerTask protected void runTimer() { checkTraceConfig(); } private void checkTraceConfig() { long traceConfigTimestamp = traceConfigFile.lastModified(); if (traceConfigTimestamp == 0) { return; } if (traceConfigTimestamp > prevTraceConfigTimestamp) { prevTraceConfigTimestamp = traceConfigTimestamp; tracer.config("Reading modified trace configuration file"); try { LogManager.getLogManager().readConfiguration(); } catch (IOException ex) { // REVIEW: do more? There's a good chance this will end // up in /dev/null. tracer.severe( "Caught IOException while updating " + "trace configuration: " + ex.getMessage()); } dumpTraceConfig(); } } } private class CheckpointTask extends FarragoTimerTask { CheckpointTask() { super(tracer); } // implement FarragoTimerTask public void runTimer() { requestCheckpoint(true, true); } } private class ReposSwitcher implements FarragoAllocation { public void closeAllocation() { userRepos = systemRepos; } } } // End FarragoDatabase.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSavepoint.java0000444000175000017500000000611411173714170025335 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSavepoint.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import net.sf.farrago.fem.fennel.*; import net.sf.farrago.fennel.*; import net.sf.farrago.session.*; /** * FarragoDbSavepoint implements the {@link * net.sf.farrago.session.FarragoSessionSavepoint} interface in terms of a * {@link FarragoDbSession}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSavepoint.java#11 $ */ class FarragoDbSavepoint implements FarragoSessionSavepoint { //~ Instance fields -------------------------------------------------------- /** * Session which created this savepoint. */ FarragoDbSession session; /** * ID generated by session (unique within session scope). */ private int id; /** * Name assigned by user, or null if unnamed. */ private String name; /** * Handle to underlying Fennel savepoint. */ private FennelSvptHandle fennelSvptHandle; //~ Constructors ----------------------------------------------------------- FarragoDbSavepoint( int id, String name, FennelSvptHandle fennelSvptHandle, FarragoDbSession session) { this.id = id; this.name = name; this.fennelSvptHandle = fennelSvptHandle; this.session = session; } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionSavepoint public int getId() { return id; } // implement FarragoSessionSavepoint public String getName() { return name; } // implement Object public boolean equals(Object obj) { if (!(obj instanceof FarragoDbSavepoint)) { return false; } FarragoDbSavepoint other = (FarragoDbSavepoint) obj; return (id == other.id) && (session == other.session); } // implement Object public int hashCode() { return id; } FennelSvptHandle getFennelSvptHandle() { return fennelSvptHandle; } } // End FarragoDbSavepoint.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSessionIndexMap.java0000444000175000017500000003075211173714170026443 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionIndexMap.java#29 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.sql.*; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.namespace.*; import net.sf.farrago.namespace.util.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.util.*; import org.eigenbase.jmi.*; /** * FarragoDbSessionIndexMap implements {@link FarragoSessionIndexMap}, resolving * indexes for both permanent and temporary tables. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionIndexMap.java#29 $ */ class FarragoDbSessionIndexMap extends FarragoCompoundAllocation implements FarragoSessionIndexMap { //~ Instance fields -------------------------------------------------------- private FarragoDbSession dbSession; /** * Map from index MOF ID to root PageId for temporary tables. */ private Map tempIndexRootMap; /** * Repos for this session. */ private FarragoRepos repos; /** * Cache for local data wrappers used to manage indexes. */ private FarragoDataWrapperCache privateDataWrapperCache; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoDbSessionIndexMap. * * @param owner FarragoAllocationOwner which will own this map; on * closeAllocation, any temporary indexes will be deleted automatically * @param dbSession FarragoDbSession context * @param repos the repos for this session */ public FarragoDbSessionIndexMap( FarragoAllocationOwner owner, FarragoDbSession dbSession, FarragoRepos repos) { this.dbSession = dbSession; this.repos = repos; tempIndexRootMap = new HashMap(); owner.addAllocation(this); privateDataWrapperCache = new FarragoDataWrapperCache( this, dbSession.getDatabase().getDataWrapperCache(), dbSession.getDatabase().getPluginClassLoader(), repos, dbSession.getDatabase().getFennelDbHandle(), null); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionIndexMap public long getIndexRoot(FemLocalIndex index) { return getIndexRoot(index, false); } // implement FarragoSessionIndexMap public long getIndexRoot(FemLocalIndex index, boolean write) { if (FarragoCatalogUtil.isIndexTemporary(index)) { Long root = tempIndexRootMap.get(index.refMofId()); assert (root != null); return root.longValue(); } else { return Long.parseLong(index.getStorageId()); } } // implement FarragoSessionIndexMap public void setIndexRoot( FemLocalIndex index, long root) { if (FarragoCatalogUtil.isIndexTemporary(index)) { Long old = tempIndexRootMap.put( index.refMofId(), new Long(root)); assert (old == null); } else { index.setStorageId(Long.toString(root)); } } // implement FarragoSessionIndexMap public void instantiateTemporaryTable( FarragoDataWrapperCache wrapperCache, CwmTable table) { assert (table.isTemporary()); FemLocalIndex clusteredIndex = FarragoCatalogUtil.getClusteredIndex(repos, table); if (tempIndexRootMap.containsKey(clusteredIndex.refMofId())) { // already instantiated this table return; } for ( FemLocalIndex index : FarragoCatalogUtil.getTableIndexes(repos, table)) { assert (!tempIndexRootMap.containsKey(index.refMofId())); createIndexStorage(wrapperCache, index); } } // implement FarragoSessionIndexMap public CwmTable getReloadTable() { return null; } // implement FarragoSessionIndexMap public CwmTable getOldTableStructure() { return null; } // implement FarragoAllocation public void closeAllocation() { repos.beginReposSession(); try { // materialize deletion list to avoid // ConcurrentModificationException List list = new ArrayList(tempIndexRootMap.keySet()); for (String indexMofId : list) { dropIndexStorage(privateDataWrapperCache, indexMofId, false); } // TODO: make Fennel drop temporary indexes on recovery also // NOTE: do this last, so that we don't release data wrappers // until we're done using them for drops above super.closeAllocation(); } finally { repos.endReposSession(); } } /** * Commit hook: truncates any indexes for tables defined with ON COMMIT * DELETE ROWS. */ public void onCommit() { for (String indexMofId : tempIndexRootMap.keySet()) { FemLocalIndex index = (FemLocalIndex) repos.getMdrRepos().getByMofId(indexMofId); String temporaryScope = FarragoCatalogUtil.getIndexTable(index).getTemporaryScope(); if (temporaryScope.endsWith("PRESERVE")) { continue; } dropIndexStorage(privateDataWrapperCache, indexMofId, true); } } // implement FarragoSessionIndexMap public void createIndexStorage( FarragoDataWrapperCache wrapperCache, FemLocalIndex index) { createIndexStorage(wrapperCache, index, true); } // REVIEW: rollback issues // implement FarragoSessionIndexMap public long createIndexStorage( FarragoDataWrapperCache wrapperCache, FemLocalIndex index, boolean updateMap) { FarragoMedLocalDataServer server = getIndexDataServer(wrapperCache, index); long indexRoot; try { indexRoot = server.createIndex(index, dbSession.getFennelTxnContext()); } catch (SQLException ex) { throw FarragoResource.instance().DataServerIndexCreateFailed.ex( repos.getLocalizedObjectName(index), ex); } if (updateMap) { setIndexRoot(index, indexRoot); } return indexRoot; } // implement FarragoSessionIndexMap public void dropIndexStorage( FarragoDataWrapperCache wrapperCache, FemLocalIndex index, boolean truncate) { dropIndexStorageImpl(wrapperCache, index, null, truncate); } // implement FarragoSessionIndexMap public void dropIndexStorage( FarragoDataWrapperCache wrapperCache, String indexMofId, boolean truncate) { dropIndexStorageImpl(wrapperCache, null, indexMofId, truncate); } private void dropIndexStorageImpl( FarragoDataWrapperCache wrapperCache, FemLocalIndex index, String indexMofId, boolean truncate) { FarragoReposTxnContext txn = repos.newTxnContext(true); if (index == null) { assert (indexMofId != null); txn.beginReadTxn(); index = (FemLocalIndex) repos.getMdrRepos().getByMofId(indexMofId); } else { assert (indexMofId == null); indexMofId = index.refMofId(); } try { if (FarragoCatalogUtil.isIndexTemporary(index)) { if (!tempIndexRootMap.containsKey(indexMofId)) { // index was never created, so nothing to do return; } } FarragoMedLocalDataServer server = getIndexDataServer(wrapperCache, index); String localizedIndexName = repos.getLocalizedObjectName(index); try { long root = getIndexRoot(index); // The dropIndex call is the potentially long-running part, so // before invoking it, end our repository transaction if we // started one. We've already been careful to dig out anything // we need from the repository by this point. txn.commit(); // FIXME jvs 11-Dec-2008: We're still passing in // the index reference here. The local data wrapper // SPI needs to be fixed to avoid this. We're probably // OK for now since the calls so far // (e.g. FarragoCatalogUtil.isIndexTemporary) will // have preloaded references needed. server.dropIndex( index, root, truncate, dbSession.getFennelTxnContext()); } catch (SQLException ex) { throw FarragoResource.instance().DataServerIndexDropFailed.ex( localizedIndexName, ex); } if (!truncate) { tempIndexRootMap.remove(indexMofId); } } finally { txn.commit(); } } // implement FarragoSessionIndexMap public FarragoMedLocalIndexStats computeIndexStats( FarragoDataWrapperCache wrapperCache, FemLocalIndex index, boolean estimate) { FarragoMedLocalDataServer server = getIndexDataServer(wrapperCache, index); try { return server.computeIndexStats( index, getIndexRoot(index), estimate, dbSession.getFennelTxnContext()); } catch (SQLException ex) { throw FarragoResource.instance().DataServerIndexVerifyFailed.ex( repos.getLocalizedObjectName(index), ex); } } // implement FarragoSessionIndexMap public FemLocalIndex getIndexById(long id) { String mofId = JmiObjUtil.toMofId(id); FemLocalIndex index = (FemLocalIndex) repos.getMdrRepos().getByMofId(mofId); return index; } private FarragoMedLocalDataServer getIndexDataServer( FarragoDataWrapperCache wrapperCache, FemLocalIndex index) { FemLocalTable localTable = (FemLocalTable) index.getSpannedClass(); return (FarragoMedLocalDataServer) wrapperCache.loadServerFromCatalog( localTable.getServer()); } public void versionIndexRoot( FarragoDataWrapperCache wrapperCache, FemLocalIndex index, Long newRoot) { FarragoMedLocalDataServer server = getIndexDataServer(wrapperCache, index); try { // Truncate the original index and then version the new index // root to the now empty root. Note that we cannot drop the // original index because that would result in losing the // original root page that we need to version. dropIndexStorage(wrapperCache, index, true); server.versionIndexRoot( getIndexRoot(index), newRoot, dbSession.getFennelTxnContext()); } catch (SQLException ex) { throw FarragoResource.instance().DataServerIndexVersionFailed.ex( repos.getLocalizedObjectName(index), ex); } } } // End FarragoDbSessionIndexMap.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbStmtContext.java0000444000175000017500000004021211173714170025656 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbStmtContext.java#56 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.sql.*; import java.util.*; import java.util.logging.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.util.*; import org.eigenbase.rel.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.runtime.*; import org.eigenbase.sql.*; import org.eigenbase.util.*; /** * FarragoDbStmtContext implements the {@link * net.sf.farrago.session.FarragoSessionStmtContext} interface in terms of a * {@link FarragoDbSession}. * *

Most non-trivial public methods on this class must be synchronized on the * parent session; see superclass for details. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbStmtContext.java#56 $ */ public class FarragoDbStmtContext extends FarragoDbStmtContextBase implements FarragoSessionStmtContext { //~ Instance fields -------------------------------------------------------- private long updateCount; private ResultSet resultSet; private FarragoSessionExecutableStmt executableStmt; private FarragoCompoundAllocation allocations; private FarragoSessionRuntimeContext runningContext; private final FarragoWarningQueue warningQueue; private boolean isExecDirect; /** * query timeout in seconds, default to 0. */ private int queryTimeoutMillis = 0; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoDbStmtContext object. * * @param session the session creating this statement */ public FarragoDbStmtContext( FarragoDbSession session, FarragoSessionStmtParamDefFactory paramDefFactory, FarragoDdlLockManager ddlLockManager) { this(session, paramDefFactory, ddlLockManager, null); } /** * Creates a new FarragoDbStmtContext object. * * @param session the session creating this statement */ public FarragoDbStmtContext( FarragoDbSession session, FarragoSessionStmtParamDefFactory paramDefFactory, FarragoDdlLockManager ddlLockManager, FarragoSessionStmtContext rootStmtContext) { super(session, paramDefFactory, ddlLockManager, rootStmtContext); updateCount = -1; warningQueue = new FarragoWarningQueue(); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionStmtContext public boolean isPrepared() { return (executableStmt != null); } // implement FarragoSessionStmtContext public boolean isPreparedDml() { return executableStmt.isDml(); } // implement FarragoSessionStmtContext public void prepare( String sql, boolean isExecDirect) { synchronized (session) { warningQueue.clearWarnings(); unprepare(); allocations = new FarragoCompoundAllocation(); this.sql = sql; this.isExecDirect = isExecDirect; executableStmt = session.prepare( this, sql, allocations, isExecDirect, null); finishPrepare(); } } private void finishPrepare() { if (isPrepared()) { final RelDataType dynamicParamRowType = executableStmt.getDynamicParamRowType(); initDynamicParams(dynamicParamRowType); } else { // always zero for DDL updateCount = 0; } } // implement FarragoSessionStmtContext public void prepare( RelNode plan, SqlKind kind, boolean logical, FarragoSessionPreparingStmt prep) { synchronized (session) { warningQueue.clearWarnings(); unprepare(); allocations = new FarragoCompoundAllocation(); this.sql = ""; // not available executableStmt = session.getDatabase().implementStmt( prep, plan, kind, logical, allocations); if (isPrepared()) { lockObjectsInUse(executableStmt); } finishPrepare(); } } // implement FarragoSessionStmtContext public RelDataType getPreparedRowType() { synchronized (session) { assert (isPrepared()); return executableStmt.getRowType(); } } // implement FarragoSessionStmtContext public RelDataType getPreparedParamType() { synchronized (session) { assert (isPrepared()); return executableStmt.getDynamicParamRowType(); } } // implement FarragoSessionStmtContext public void setQueryTimeout(int millis) { queryTimeoutMillis = millis; } // implement FarragoSessionStmtContext public int getQueryTimeout() { return queryTimeoutMillis; } // implement FarragoSessionStmtContext public void execute() { synchronized (session) { executeImpl(); } } private void executeImpl() { assert (isPrepared()); if (!isExecDirect) { warningQueue.clearWarnings(); } closeResultSet(); traceExecute(); boolean isDml = executableStmt.isDml(); boolean success = false; if (session.isAutoCommit()) { // REVIEW jvs 26-Nov-2006: What about CALL? Maybe // we can start it as read-only (regardless of // whether the statements inside are DML, since they // will do their own autocommits). startAutocommitTxn(!isDml); if ((rootStmtContext != null) && rootStmtContext.needToSaveFirstTxnCsn()) { rootStmtContext.saveFirstTxnCsn( session.getFennelTxnContext().getTxnCsn()); } } session.getRepos().beginReposSession(); FarragoSessionRuntimeContext newContext = null; try { checkDynamicParamsSet(); FarragoSessionRuntimeParams params = session.newRuntimeContextParams(); if (executableStmt.getTableModOp() == null) { // only use txnCodeCache for real DML, not CALL params.txnCodeCache = null; } // FIXME: using Statement-level queue, but should use // ResultSet-level queue for isDml=false params.warningQueue = warningQueue; params.isDml = isDml; params.resultSetTypeMap = executableStmt.getResultSetTypeMap(); params.iterCalcTypeMap = executableStmt.getIterCalcTypeMap(); params.dynamicParamValues = dynamicParamValues; // REVIEW zfong 3/21/08 - Should this time be set to a non-zero // value even if this isn't an internal statement? Currently, // it is, and therefore, it means that the current time is always // set based on the time when the statement was created, rather // than executed. params.currentTime = getStmtCurrentTime(); assert (runningContext == null); initExecutingStmtInfo(executableStmt); params.stmtId = getExecutingStmtInfo().getId(); newContext = session.getPersonality().newRuntimeContext(params); if (allocations != null) { newContext.addAllocation(allocations); allocations = null; } if (daemon) { newContext.addAllocation(this); } // Acquire locks (or whatever transaction manager wants) on all // tables accessed by this statement. accessTables(executableStmt); // If cancel request already came in, propagate it to // new context, which will then see it as part of execution. if (cancelFlag.isCancelRequested()) { newContext.cancel(); } resultSet = executableStmt.execute(newContext); runningContext = newContext; newContext = null; if (queryTimeoutMillis > 0) { AbstractIterResultSet iteratorRS = (AbstractIterResultSet) resultSet; iteratorRS.setTimeout(queryTimeoutMillis); } success = true; } finally { if (newContext != null) { newContext.closeAllocation(); newContext = null; } if (!success) { session.endTransactionIfAuto(false); if (resultSet == null) { session.getRepos().endReposSession(); } } } if (isDml) { success = false; List rowCounts = new ArrayList(); try { session.getPersonality().getRowCounts( resultSet, rowCounts, executableStmt.getTableModOp()); updateCount = updateRowCounts(rowCounts, runningContext); success = true; if (tracer.isLoggable(Level.FINE)) { tracer.fine("Update count = " + updateCount); } } catch (SQLException ex) { throw FarragoResource.instance().DmlFailure.ex(ex); } finally { try { resultSet.close(); } catch (SQLException ex) { throw Util.newInternal(ex); } finally { resultSet = null; runningContext = null; if (!success) { session.endTransactionIfAuto(false); } clearExecutingStmtInfo(); } } } // NOTE: for result sets, autocommit is taken care of by // FarragoTupleIterResultSet and FennelTxnContext if (resultSet == null) { session.endTransactionIfAuto(true); if (!isDml) { session.getRepos().endReposSession(); } } if (session.shutdownRequested()) { session.closeAllocation(); FarragoDatabase db = ((FarragoDbSession) session).getDatabase(); db.shutdown(); session.setShutdownRequest(false); } } // implement FarragoSessionStmtContext public ResultSet getResultSet() { return resultSet; } // implement FarragoSessionStmtContext public long getUpdateCount() { synchronized (session) { long count = updateCount; updateCount = -1; return count; } } // implement FarragoSessionStmtContext public void cancel() { // request cancel, but don't wait for it to take effect cancel(false); } private void cancel(boolean wait) { tracer.info("cancel"); // First, see if there are any child contexts that need to be // canceled for (FarragoSessionStmtContext childStmtContext : childrenStmtContexts) { childStmtContext.cancel(); } // Record the cancellation request even if we haven't started // a runtime context yet. We'll check this once the // runtime context gets created (FRG-349). cancelFlag.requestCancel(); FarragoSessionRuntimeContext contextToCancel = runningContext; if (contextToCancel == null) { return; } contextToCancel.cancel(); if (wait) { // if the cursor was executing when the cancel request was // received, this will wait for it to finish and return; // after that, it's safe to proceed with cleanup, since // any further fetch requests will see the cancel flag // already set and fail immediately contextToCancel.waitForCursor(); } } // implement FarragoSessionStmtContext public void kill() { cancel(true); closeAllocation(); } // implement FarragoSessionStmtContext public void closeResultSet() { synchronized (session) { if (resultSet == null) { return; } try { resultSet.close(); } catch (Throwable ex) { throw Util.newInternal(ex); } resultSet = null; FarragoSessionRuntimeContext contextToClose = runningContext; if (contextToClose != null) { contextToClose.closeAllocation(); } runningContext = null; clearExecutingStmtInfo(); } } // implement FarragoSessionStmtContext public void unprepare() { synchronized (session) { // request cancel, and wait until it takes effect before // proceeding with cleanup, otherwise we may yank stuff // out from under executing threads in a bad way cancel(true); closeResultSet(); if (allocations != null) { allocations.closeAllocation(); allocations = null; } // reset the csn now that we've unprepared the root stmt context if (rootStmtContext == null) { snapshotCsn = null; } executableStmt = null; isExecDirect = false; super.unprepare(); } } // implement FarragoSessionStmtContext public FarragoWarningQueue getWarningQueue() { return warningQueue; } /** * Update catalog row counts * * @param rowCounts row counts returned by the DML operation * * @return rowcount affected by the DML operation */ private long updateRowCounts( List rowCounts, FarragoSessionRuntimeContext runningContext) { TableModificationRel.Operation tableModOp = executableStmt.getTableModOp(); // marked as DML, but doesn't actually modify a table; e.g., a // procedure call if (tableModOp == null) { return 0; } List targetTable = getDmlTarget(); // if there's no target table (e.g., for a create index), then this // isn't really a DML statement if (targetTable == null) { return 0; } return session.getPersonality().updateRowCounts( session, targetTable, rowCounts, executableStmt.getTableModOp(), runningContext); } private List getDmlTarget() { TableAccessMap tableAccessMap = executableStmt.getTableAccessMap(); Set> tablesAccessed = tableAccessMap.getTablesAccessed(); for (List table : tablesAccessed) { if (tableAccessMap.isTableAccessedForWrite(table)) { return table; } } return null; } } // End FarragoDbStmtContext.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSessionPrivilegeChecker.java0000444000175000017500000001341211173714170030143 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionPrivilegeChecker.java#14 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; /** * Implements the {@link FarragoSessionPrivilegeChecker} interface in the * context of a {@link FarragoDbSession}. * *

An instance of this class must be created per statement i.e. it can't be * shared between statements. * * @author Tai Tran * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionPrivilegeChecker.java#14 $ */ public class FarragoDbSessionPrivilegeChecker implements FarragoSessionPrivilegeChecker { //~ Instance fields -------------------------------------------------------- private final FarragoSession session; private final Map, Set> authMap; private FemRole publicRole; //~ Constructors ----------------------------------------------------------- public FarragoDbSessionPrivilegeChecker(FarragoSession session) { this.session = session; authMap = new HashMap, Set>(); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionPrivilegeChecker public void requestAccess( CwmModelElement obj, FemUser user, FemRole role, String action) { List authKey = new ArrayList(2); authKey.add(user); authKey.add(role); // Find credentials for the given user and role. Set authSet = authMap.get(authKey); if (authSet == null) { // Compute all credentials for the given user and role. authSet = new HashSet(); authMap.put(authKey, authSet); if (user != null) { authSet.add(user); } if (role != null) { authSet.add(role); inheritRoles(role, authSet); } authSet.add(getPublicRole()); } // Now, let's check their papers... if (testAccess(obj, authSet, action)) { // It's all good. return; } // Verboten! throw FarragoResource.instance().ValidatorAccessDenied.ex( session.getRepos().getLocalizedObjectName(action), session.getRepos().getLocalizedObjectName(obj)); } private FemRole getPublicRole() { if (publicRole == null) { publicRole = FarragoCatalogUtil.getRoleByName( session.getRepos(), FarragoCatalogInit.PUBLIC_ROLE_NAME); } return publicRole; } // implement FarragoSessionPrivilegeChecker public void checkAccess() { // This implementation does all the work immediately in requestAccess, // so nothing to do here. } private void inheritRoles(FemRole role, Set inheritedRoles) { String inheritAction = PrivilegedActionEnum.INHERIT_ROLE.toString(); for (FemGrant grant : role.getGranteePrivilege()) { if (grant.getAction().equals(inheritAction)) { FemRole inheritedRole = (FemRole) grant.getElement(); // sanity check: DDL validation is supposed to prevent // cycles assert (!inheritedRoles.contains(inheritedRole)); inheritedRoles.add(inheritedRole); inheritRoles(inheritedRole, inheritedRoles); } } } private boolean testAccess( CwmModelElement obj, Set authSet, String action) { SecurityPackage sp = session.getRepos().getSecurityPackage(); boolean sawCreationGrant = false; for (Object o : sp.getPrivilegeIsGrantedOnElement().getPrivilege(obj)) { FemGrant grant = (FemGrant) o; boolean isCreation = grant.getAction().equals( PrivilegedActionEnum.CREATION.toString()); if (isCreation) { sawCreationGrant = true; } if (authSet.contains(grant.getGrantee()) && (grant.getAction().equals(action) || isCreation)) { return true; } } if (sawCreationGrant) { return false; } else { // We didn't see a creation grant. The only way that's possible is // that obj is currently in the process of being created. In that // case, whatever object is referencing it must have the same // creator, so no explicit privilege is required. return true; } } } // End FarragoDbSessionPrivilegeChecker.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoDbSessionFactory.java0000444000175000017500000001246611173714170026347 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionFactory.java#31 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.fennel.*; import net.sf.farrago.plugin.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.util.*; /** * FarragoDbSessionFactory is a basic implementation for the {@link * net.sf.farrago.session.FarragoSessionFactory} interface. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoDbSessionFactory.java#31 $ */ public class FarragoDbSessionFactory implements FarragoSessionFactory { //~ Methods ---------------------------------------------------------------- // implement FarragoSessionFactory public FarragoSession newSession( String url, Properties info) { return new FarragoDbSession(url, info, this); } // implement FarragoSessionFactory public FarragoSession newReentrantSession(FarragoSession session) { // REVIEW jvs 9-Jan-2007: Seems like this is redundant, // since cloneSession is going to clone the variables again. FarragoSessionVariables sessionVars = session.getSessionVariables().cloneVariables(); FarragoSession reentrantSession = session.cloneSession(sessionVars); return reentrantSession; } // implement FarragoSessionFactory public void releaseReentrantSession(FarragoSession session) { session.closeAllocation(); } // implement FarragoSessionPersonalityFactory public FarragoSessionPersonality newSessionPersonality( FarragoSession session, FarragoSessionPersonality defaultPersonality) { if (defaultPersonality == null) { throw new UnsupportedOperationException( "no default session personality defined"); } else { return defaultPersonality; } } // implement FarragoSessionFactory public FarragoSessionModelExtension newModelExtension( FarragoPluginClassLoader pluginClassLoader, FemJar femJar) { String url = FarragoCatalogUtil.getJarUrl(femJar); try { String attr = FarragoPluginClassLoader.PLUGIN_FACTORY_CLASS_ATTRIBUTE; Class factoryClass = pluginClassLoader.loadClassFromJarUrlManifest(url, attr); FarragoSessionModelExtensionFactory factory = (FarragoSessionModelExtensionFactory) pluginClassLoader .newPluginInstance(factoryClass); // TODO: trace info about extension FarragoSessionModelExtension modelExtension = factory.newModelExtension(); return modelExtension; } catch (Throwable ex) { throw FarragoResource.instance().PluginInitFailed.ex(url, ex); } } // implement FarragoSessionFactory public FennelCmdExecutor newFennelCmdExecutor() { return new FennelCmdExecutorImpl(); } // implement FarragoSessionFactory public FarragoRepos newRepos( FarragoAllocationOwner owner, boolean userRepos) { return new FarragoMdrReposImpl( owner, new FarragoModelLoader(), userRepos); } // implement FarragoSessionFactory public FennelTxnContext newFennelTxnContext( FarragoRepos repos, FennelDbHandle fennelDbHandle) { return new FennelTxnContext(repos, fennelDbHandle); } // implement FarragoSessionFactory public FarragoSessionTxnMgr newTxnMgr() { return new FarragoDbNullTxnMgr(); } // implement FarragoSessionFactory public void applyFennelExtensionParameters(Properties map) { } // implement FarragoSessionFactory public void specializedInitialization(FarragoAllocationOwner owner) { } // implement FarragoSessionFactory public void specializedShutdown() { } // implement FarragoSessionFactory public void cleanupSessions() { FarragoDbSingleton.shutdownConditional(0); } // implement FarragoSessionFactory public void defineResourceBundles(List bundleList) { bundleList.add(FarragoResource.instance()); } } // End FarragoDbSessionFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/db/FarragoNoninteractiveCallbackHandler.java0000444000175000017500000000551311173714170031024 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoNoninteractiveCallbackHandler.java#5 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.db; import java.io.*; import javax.security.auth.callback.*; /** * Callback handler for situations where user/pass is already retrieved. * * @author ogothberg * @version $Id: //open/dev/farrago/src/net/sf/farrago/db/FarragoNoninteractiveCallbackHandler.java#5 $ */ public class FarragoNoninteractiveCallbackHandler implements CallbackHandler { //~ Instance fields -------------------------------------------------------- String user, pass; //~ Constructors ----------------------------------------------------------- public FarragoNoninteractiveCallbackHandler(String user, String pass) { this.user = user; this.pass = ((pass == null) ? "" : pass); } //~ Methods ---------------------------------------------------------------- public void clearPassword() { pass = ""; } /** * Just pass through user/pass to the corresponding callbacks */ public void handle(Callback [] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { ((NameCallback) callbacks[i]).setName(user); } else if (callbacks[i] instanceof PasswordCallback) { ((PasswordCallback) callbacks[i]).setPassword( pass.toCharArray()); } else { throw (new UnsupportedCallbackException( callbacks[i], "Unsupported callback class")); } } // user/pass have been passed on to callbacks, // don't keep them in the handler user = null; pass = null; } } // End FarragoNoninteractiveCallbackHandler.java eigenbase-farrago-0.9.0/src/net/sf/farrago/dynamic/0000755000175000017500000000000011173714170022011 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/dynamic/package.html0000444000175000017500000000137111173714170024272 0ustar drazzibdrazzib Package net.sf.farrago.dynamic Package containing dynamically generated classes which implement SQL queries and DML statements.


This package contains no real source code. However, at runtime, classes are generated in this package, so this description is here as a placeholder.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/dynamic/package.html#7 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/0000755000175000017500000000000011173714170021777 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoModelLoader.java0000444000175000017500000001416211173714170026335 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoModelLoader.java#21 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.io.*; import java.util.*; import java.util.logging.*; import net.sf.farrago.*; import net.sf.farrago.resource.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.netbeans.api.mdr.*; import org.netbeans.mdr.persistence.jdbcimpl.*; // NOTE: This class gets compiled independently of everything else since // it is used by build-time utilities such as ProxyGen. That means it must // have minimal dependencies on other non-model-generated Farrago code. // It probably needs to be moved somewhere else. /** * FarragoModelLoader is a utility class for loading the catalog model. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoModelLoader.java#21 $ */ public class FarragoModelLoader { //~ Static fields/initializers --------------------------------------------- // NOTE jvs 15-Dec-2005: Do it this way to avoid dependency on // FarragoTrace. private static final Logger tracer = Logger.getLogger("net.sf.farrago.catalog.FarragoRepos"); //~ Instance fields -------------------------------------------------------- protected EnkiMDRepository mdrRepos; private boolean openMdrReposSession; private String storageFactoryClassName; private final Properties storageProps; private final FarragoProperties farragoProperties; //~ Constructors ----------------------------------------------------------- public FarragoModelLoader() { this(FarragoProperties.instance()); } public FarragoModelLoader(FarragoProperties farragoProperties) { this.farragoProperties = farragoProperties; storageProps = new Properties(); } //~ Methods ---------------------------------------------------------------- public void close() { if (mdrRepos != null) { closeMdrSession(); mdrRepos.shutdown(); mdrRepos = null; } } public void closeMdrSession() { if (openMdrReposSession) { openMdrReposSession = false; mdrRepos.endSession(); } } public MDRepository getMdrRepos() { return mdrRepos; } public FarragoPackage loadModel( String extentName, boolean userRepos) { initStorage(userRepos); return (FarragoPackage) mdrRepos.getExtent(extentName); } public void initStorage(boolean userRepos) { if (userRepos) { setUserReposProperties(); } else { try { setSystemReposProperties(); } catch (IOException ex) { throw FarragoResource.instance().CatalogPropsAccessFailed.ex( getSystemReposFile().getAbsolutePath(), ex); } } mdrRepos = MdrUtil.loadRepository(storageFactoryClassName, storageProps); mdrRepos.beginSession(); openMdrReposSession = true; } public File getSystemReposFile() { File catalogDir = farragoProperties.getCatalogDir(); return new File(catalogDir, "ReposStorage.properties"); } private void setSystemReposProperties() throws IOException { File reposFile = getSystemReposFile(); InputStream propsStream = new FileInputStream(reposFile); Properties props = new Properties(); try { props.load(propsStream); } finally { propsStream.close(); } //noinspection unchecked final Map map = (Map) props; for (Map.Entry entry : map.entrySet()) { setStorageProperty( entry.getKey(), farragoProperties.expandProperties( entry.getValue())); } } private void setUserReposProperties() { // REVIEW: SWZ: 2008-02-12: This will fail badly if used with // Enki+Hibernate. storageFactoryClassName = JdbcStorageFactory.class.getName(); setStorageProperty(JdbcStorageFactory.STORAGE_URL, "jdbc:farrago:"); setStorageProperty(JdbcStorageFactory.STORAGE_USER_NAME, "MDR"); setStorageProperty(JdbcStorageFactory.STORAGE_SCHEMA_NAME, "MDR"); setStorageProperty( JdbcStorageFactory.STORAGE_DRIVER_CLASS_NAME, "net.sf.farrago.jdbc.engine.FarragoJdbcEngineDriver"); setStorageProperty( JdbcStorageFactory.STORAGE_DATATYPE_STREAMABLE, "VARBINARY(10000)"); } private void setStorageProperty( String name, String value) { tracer.fine( "Setting repository storage property '" + name + "' = [ " + value + " ]"); storageProps.put(name, value); } public Properties getStorageProperties() { return storageProps; } public String getStorageFactoryClassName() { return JdbcStorageFactory.class.getName(); } public FarragoProperties getFarragoProperties() { return farragoProperties; } } // End FarragoModelLoader.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoTableStatistics.java0000444000175000017500000000713411173714170027251 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoTableStatistics.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.sql.*; import java.util.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.fem.sql2003.*; import org.eigenbase.sarg.*; import org.eigenbase.stat.*; /** * This class reads statistics for a Farrago table from data stored in the * catalog. * * @author John Pham * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoTableStatistics.java#10 $ */ public class FarragoTableStatistics implements RelStatSource { //~ Instance fields -------------------------------------------------------- private FarragoRepos repos; private FemAbstractColumnSet table; private Timestamp labelTimestamp; //~ Constructors ----------------------------------------------------------- /** * Initialize an object for retrieving table statistics * * @param repos the repository containing stats * @param table the table for which to retrieve stats * * @deprecated */ public FarragoTableStatistics( FarragoRepos repos, FemAbstractColumnSet table) { this(repos, table, null); } /** * Initialize an object for retrieving table statistics, optionally based on * a label setting. * * @param repos the repository containing stats * @param table the table for which to retrieve stats * @param labelTimestamp the creation timestamp of the label that determines * which stats to retrieve; null if there is no label setting */ public FarragoTableStatistics( FarragoRepos repos, FemAbstractColumnSet table, Timestamp labelTimestamp) { this.repos = repos; this.table = table; this.labelTimestamp = labelTimestamp; } //~ Methods ---------------------------------------------------------------- // implement RelStatSource public Double getRowCount() { Long [] rowCounts = new Long[2]; FarragoCatalogUtil.getRowCounts( table, labelTimestamp, rowCounts); return (rowCounts[0] == null) ? null : Double.valueOf(rowCounts[0]); } // implement RelStatSource public RelStatColumnStatistics getColumnStatistics( int ordinal, SargIntervalSequence predicate) { List features = table.getFeature(); FemAbstractColumn column = (FemAbstractColumn) features.get(ordinal); FarragoColumnHistogram result = new FarragoColumnHistogram(column, predicate, labelTimestamp); result.evaluate(); return result; } } // End FarragoTableStatistics.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoMdrReposImpl.java0000444000175000017500000002310211173714170026515 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoMdrReposImpl.java#22 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.io.*; import java.util.*; import java.util.logging.*; import javax.jmi.model.*; import javax.jmi.reflect.*; import net.sf.farrago.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.fem.fennel.*; import net.sf.farrago.resource.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.eigenbase.jmi.mem.*; import org.netbeans.api.mdr.*; /** * Implementation of {@link FarragoRepos} using a MDR repository. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoMdrReposImpl.java#22 $ */ public class FarragoMdrReposImpl extends FarragoReposImpl { //~ Static fields/initializers --------------------------------------------- private static final Logger tracer = FarragoTrace.getReposTracer(); //~ Instance fields -------------------------------------------------------- /** * Root package in transient repository. */ private final FarragoPackage transientFarragoPackage; /** * Fennel package in repository. */ private final FennelPackage fennelPackage; /** * The loader for the underlying MDR repository. */ private FarragoModelLoader modelLoader; /** * The underlying MDR repository. */ private final EnkiMDRepository mdrRepository; /** * MofId for current instance of FemFarragoConfig. */ private final String currentConfigMofId; protected FarragoMemFactory memFactory; //~ Constructors ----------------------------------------------------------- /** * Opens a Farrago repository. */ public FarragoMdrReposImpl( FarragoAllocationOwner owner, FarragoModelLoader modelLoader, boolean userRepos) { super(owner); this.modelLoader = modelLoader; tracer.fine("Loading catalog"); if (FarragoProperties.instance().homeDir.get() == null) { throw FarragoResource.instance().MissingHomeProperty.ex( FarragoProperties.instance().homeDir.getPath()); } MdrUtil.integrateTracing(FarragoTrace.getMdrTracer()); if (!userRepos) { File lockFile = new File( modelLoader.getSystemReposFile().toString() + ".lck"); try { new FarragoFileLockAllocation(allocations, lockFile, true); } catch (IOException ex) { throw FarragoResource.instance().CatalogFileLockFailed.ex( lockFile.toString()); } } if (FarragoReposUtil.isReloadNeeded(modelLoader)) { try { FarragoReposUtil.reloadRepository(modelLoader); } catch (Exception ex) { throw FarragoResource.instance().CatalogReloadFailed.ex(ex); } } FarragoPackage farragoPackage = modelLoader.loadModel("FarragoCatalog", userRepos); if (farragoPackage == null) { throw FarragoResource.instance().CatalogUninitialized.ex(); } super.setRootPackage(farragoPackage); mdrRepository = (EnkiMDRepository) modelLoader.getMdrRepos(); checkModelTimestamp("FarragoCatalog"); // Load configuration currentConfigMofId = getDefaultConfig().refMofId(); initGraph(); // Create special in-memory storage for transient objects try { memFactory = new FarragoMemFactory(getModelGraph()); transientFarragoPackage = memFactory.getFarragoPackage(); fennelPackage = transientFarragoPackage.getFem().getFennel(); } catch (Throwable ex) { throw FarragoResource.instance().CatalogInitTransientFailed.ex(ex); } finally { // End session started in modelLoader.loadModel modelLoader.closeMdrSession(); } tracer.info("Catalog successfully loaded"); } //~ Methods ---------------------------------------------------------------- private void checkModelTimestamp(String extentName) { String prefix = "TIMESTAMP = "; mdrRepository.beginTrans(true); boolean rollback = true; try { String storedTimestamp = mdrRepository.getAnnotation(extentName); String compiledTimestamp = prefix + getCompiledModelTimestamp(); if ((storedTimestamp == null) || !storedTimestamp.startsWith(prefix)) { // first time: add timestamp mdrRepository.setAnnotation(extentName, compiledTimestamp); rollback = false; } else { // on reload: verify timestamps if (!storedTimestamp.equals(compiledTimestamp)) { throw FarragoResource.instance() .CatalogModelTimestampCheckFailed.ex( storedTimestamp, compiledTimestamp); } } } finally { mdrRepository.endTrans(rollback); } } // implement FarragoRepos public MDRepository getMdrRepos() { return mdrRepository; } // implement FarragoRepos public EnkiMDRepository getEnkiMdrRepos() { return mdrRepository; } // implement FarragoRepos public FarragoPackage getTransientFarragoPackage() { return transientFarragoPackage; } // override FarragoMetadataFactory public FennelPackage getFennelPackage() { // NOTE jvs 5-May-2004: return the package corresponding to // in-memory storage return fennelPackage; } // implement FarragoRepos public FemFarragoConfig getCurrentConfig() { // TODO: prevent updates return (FemFarragoConfig) getEnkiMdrRepos().getByMofId( currentConfigMofId, getConfigPackage().getFemFarragoConfig()); } // implement FarragoAllocation public void closeAllocation() { allocations.closeAllocation(); if (modelLoader == null) { return; } tracer.fine("Closing catalog"); if (transientFarragoPackage != null) { transientFarragoPackage.refDelete(); } memFactory = null; modelLoader.close(); modelLoader = null; tracer.info("Catalog successfully closed"); } // implement FarragoRepos public void beginReposSession() { tracer.fine("Begin repository session"); super.beginReposSession(); mdrRepository.beginSession(); } // implement FarragoRepos public void beginReposTxn(boolean writable) { if (writable) { tracer.fine("Begin read/write repository transaction"); } else { tracer.fine("Begin read-only repository transaction"); } mdrRepository.beginTrans(writable); } // implement FarragoRepos public void endReposTxn(boolean rollback) { if (rollback) { tracer.fine("Rollback repository transaction"); } else { tracer.fine("Commit repository transaction"); } mdrRepository.endTrans(rollback); } // implement FarragoRepos public void endReposSession() { tracer.fine("End repository session"); super.endReposSession(); mdrRepository.endSession(); } // implement FarragoRepos public FarragoModelLoader getModelLoader() { return modelLoader; } //~ Inner Classes ---------------------------------------------------------- protected class FarragoMemFactory extends FarragoMetadataFactoryImpl { private final FactoryImpl factoryImpl; public FarragoMemFactory(JmiModelGraph modelGraph) { factoryImpl = new FactoryImpl(modelGraph); this.setRootPackage((FarragoPackage) factoryImpl.getRootPackage()); } public FactoryImpl getImpl() { return factoryImpl; } public T newRefPackage(Class ifacePackage) { return factoryImpl.newRefPackage(ifacePackage); } } private class FactoryImpl extends JmiModeledMemFactory { FactoryImpl(JmiModelGraph modelGraph) { super(modelGraph); } protected RefPackageImpl newRootPackage() { return new RefPackageImpl(FarragoPackage.class); } } } // End FarragoMdrReposImpl.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoSequenceOptions.java0000444000175000017500000002164411173714170027275 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoSequenceOptions.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.util.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.resource.*; import org.eigenbase.reltype.*; import org.eigenbase.sql.type.*; import org.eigenbase.util.*; /** * A class for tracking sequence generator options. * * @author John Pham * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoSequenceOptions.java#7 $ */ public class FarragoSequenceOptions { //~ Enums ------------------------------------------------------------------ private enum OptionType { START, INCREMENT, MINVALUE, MAXVALUE, CYCLE; } //~ Instance fields -------------------------------------------------------- private String name; private Properties props; private boolean generatedAlways; private long lowerLimit, upperLimit; private RelDataType dataType; //~ Constructors ----------------------------------------------------------- public FarragoSequenceOptions(String name) { this.name = name; props = new Properties(); } //~ Methods ---------------------------------------------------------------- public void setGeneratedAlways(boolean value) { generatedAlways = value; } public boolean getGeneratedAlways() { return generatedAlways; } public void setStart(Long value) { setOption(OptionType.START, value); } public Long getStart() { return (Long) getOption(OptionType.START); } public void setIncrement(Long value) { setOption(OptionType.INCREMENT, value); } public Long getIncrement() { return (Long) getOption(OptionType.INCREMENT); } public void setMin(Long value) { setOption(OptionType.MINVALUE, value); } public Long getMin() { return (Long) getOption(OptionType.MINVALUE); } private long getMinResolved(long minDefault) { Long minOption = getMin(); return (minOption == null) ? minDefault : minOption; } public void setMax(Long value) { setOption(OptionType.MAXVALUE, value); } public Long getMax() { return (Long) getOption(OptionType.MAXVALUE); } private long getMaxResolved(long maxDefault) { Long maxOption = getMax(); return (maxOption == null) ? maxDefault : maxOption; } public void setCycle(Boolean value) { setOption(OptionType.CYCLE, value); } public Boolean getCycle() { return (Boolean) getOption(OptionType.CYCLE); } private void setOption(OptionType opt, Object value) { if (isSet(opt)) { FarragoResource.instance().ValidatorDuplicateSequenceOption.ex( opt.toString(), name); } props.put(opt, value); } private Object getOption(OptionType opt) { return props.get(opt); } private boolean isSet(OptionType opt) { return props.containsKey(opt); } /** * Initialize a newly created sequence */ public void init( FemSequenceGenerator sequence, RelDataType dataType) { applyTo(sequence, dataType, true); } /** * Alter an existing sequence based upon options */ public void alter( FemSequenceGenerator sequence, RelDataType dataType) { applyTo(sequence, dataType, false); } /** * Apply options to a sequence * * @param sequence the sequence to be modified * @param dataType the data type of the sequence * @param create whether to begin with existing sequence */ private void applyTo( FemSequenceGenerator sequence, RelDataType dataType, boolean create) { validateType(dataType); Long start; long increment, min, max; boolean cycle, expired; if (create) { // set most default values, except start, // which is based on other values start = null; increment = 1L; min = 0L; max = upperLimit; cycle = false; expired = false; } else { // load values from existing sequence start = sequence.getBaseValue(); increment = sequence.getIncrement(); min = sequence.getMinValue(); max = sequence.getMaxValue(); cycle = sequence.isCycle(); expired = sequence.isExpired(); } // apply options and defaults Enumeration keys = props.keys(); while (keys.hasMoreElements()) { OptionType key = (OptionType) keys.nextElement(); switch (key) { case START: start = getStart(); expired = false; break; case INCREMENT: increment = getIncrement(); break; case MINVALUE: min = getMinResolved(0L); break; case MAXVALUE: max = getMaxResolved(upperLimit); break; case CYCLE: cycle = getCycle(); break; default: Util.permAssert( false, "invalid sequence option"); } } if (create && (start == null)) { start = (increment > 0) ? min : max; } // validate values validateValue(start); validateValue(increment); validateValue(min); validateValue(max); // allow alter sequence to reenable an expired sequence if (expired) { long nextVal = start + increment; boolean sufficientRange = (increment > 0) ? (nextVal <= max) : (nextVal >= min); if (sufficientRange) { start = nextVal; expired = false; } else if (cycle) { start = (increment > 0) ? min : max; expired = false; } } if (increment == 0) { throw FarragoResource.instance().ValidatorZeroSequenceIncrement.ex( name); } if (min > max) { throw FarragoResource.instance().ValidatorInvalidSequenceMin.ex( min, max); } if ((min > start) || (start > max)) { throw FarragoResource.instance().ValidatorInvalidSequenceStart.ex( start, min, max); } // initialize sequence sequence.setBaseValue(start); sequence.setIncrement(increment); sequence.setMinValue(min); sequence.setMaxValue(max); sequence.setCycle(cycle); sequence.setExpired(expired); } /** * Validates and sets data type of sequence */ private void validateType(RelDataType dataType) { if (!SqlTypeUtil.isExactNumeric(dataType)) { throw FarragoResource.instance().ValidatorInexactSequenceType.ex( name); } int precision = dataType.getPrecision(); if (precision > SqlTypeName.MAX_NUMERIC_PRECISION) { // allow the validator to catch this error later return; } if (dataType.getScale() != 0) { throw FarragoResource.instance().ValidatorScaleMustBeZero.ex( name); } lowerLimit = SqlTypeUtil.getMinValue(dataType); upperLimit = SqlTypeUtil.getMaxValue(dataType); this.dataType = dataType; } /** * Validates that value is within range of specified type */ private void validateValue(long value) { if ((value < lowerLimit) || (value > upperLimit)) { throw FarragoResource.instance().ParameterValueOutOfRange.ex( Long.toString(value), dataType.toString()); } } } // End FarragoSequenceOptions.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/MockFarragoMetadataFactory.java0000444000175000017500000000371111173714170030026 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/MockFarragoMetadataFactory.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import net.sf.farrago.*; /** * Mock implementation of {@link FarragoMetadataFactory}. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/MockFarragoMetadataFactory.java#7 $ */ public class MockFarragoMetadataFactory extends FarragoMetadataFactoryImpl { //~ Constructors ----------------------------------------------------------- public MockFarragoMetadataFactory() { super(); MockMetadataFactory factoryImpl = new FactoryImpl(); this.setRootPackage((FarragoPackage) factoryImpl.getRootPackage()); } //~ Inner Classes ---------------------------------------------------------- private static class FactoryImpl extends MockMetadataFactory { protected RefPackageImpl newRootPackage() { return new RefPackageImpl(FarragoPackage.class); } } } // End MockFarragoMetadataFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/package.html0000444000175000017500000001031511173714170024256 0ustar drazzibdrazzib Package net.sf.farrago.catalog Implements the Farrago metadata catalog.
The Farrago catalog is implemented as an instance of the Netbeans MDR repository. {@link net.sf.farrago.catalog.FarragoRepos} takes care of starting up and shutting down the repository, as well as exposing root packages and providing utilities for querying and updating the catalog.

Catalog Build

The diagram below provides an overview of the build-time processing which orchestrates catalog definition and access:

There are two inputs to the process:
  • The standard CWM data warehouse metamodel. The XMI definition for this metamodel is provided by OMG.
  • Farrago-specific extensions, referred to as FEM (the Farrago Extension Metamodel). The UML definition for this metamodel is maintained by the Farrago developers (using the community edition of the Poseidon UML modeling tool from Gentleware.

The first step of the catalog build is to combine the two models into a single XMI file before further processing. This requires a bit of XMI massaging; custom XSL scripts make this reasonably painless. (Since MDR uses MOF, we use the UML2MOF tool to convert FEM.) Some filtering is also performed; for example, Farrago only uses the following CWM packages:

  • org.omg::CWM::ObjectModel::Behavioral
  • org.omg::CWM::ObjectModel::Core
  • org.omg::CWM::ObjectModel::Instance
  • org.omg::CWM::Foundation::DataTypes
  • org.omg::CWM::Foundation::KeysIndexes

Next, the combined metamodel is imported into a new MDR repository instance and stored in an extent named FarragoMetamodel. A singleton instance of this metamodel is instantiated with extent name FarragoCatalog; this will store actual catalog data.

Besides storage, model-specific Java interfaces are also required for accessing the catalog at runtime. For example, a table is represented by {@link net.sf.farrago.cwm.relational.CwmTable}. The build calls MDR to generate these from the metamodel. The CWM interfaces are generated under package {@link net.sf.farrago.cwm}, and the FEM interfaces are generated under package {@link net.sf.farrago.fem}. Custom code-generators in {@link net.sf.farrago.catalog.codegen } take care of generating convenience class {@link net.sf.farrago.FarragoMetadataFactory } and C++ code used for JNI access to the model (TODO: link).

As shown at the bottom of the diagram, a DTD is also generated which describes the XMI format of catalog import/export data (all of which is implemented by MDR).

For more details on the build process, please study the createCatalog target in //open/dev/farrago/build.xml.

Catalog Population

In addition to preparing an empty catalog, the build also populates it with some initial metadata. Currently, this includes:
  • supported datatypes
  • builtin data wrappers needed by system
  • internal schema defining JDBC metadata views
  • sample schemas and data wrappers
  • initial configuration information
Eventually, this will include many other things such as the INFORMATION_SCHEMA definition, lists of supported functions, system-owned schemas and procedures, etc. (The sample SALES schema is only for developer testing and will not be present in released distributions.)

Once the system is fully initialized, DDL statements executed by users can also modify the catalog. The geneneric DDL implementation is in {@link net.sf.farrago.ddl}. Specific validation and storage rules for various catalog objects are supplied by {@link net.sf.farrago.ddl.DdlHandler}.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/catalog/package.html#9 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FemSqltypedElement.java0000444000175000017500000000721211173714170026411 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FemSqltypedElement.java#9 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.fem.sql2003.*; /** * This interface belongs in the UML model, but can't live there due to * metamodel problems. That's the short story. * *

You want the unabridged version? CWM declares a number of important * attributes on CwmColumn, but the same attributes are needed on other classes * such as FemRoutineParameter, and they aren't present on the base class * CwmSqlparameter. Validation code would like to be able to handle any kind of * SQL-typed object uniformly, so a common interface is required. * FemRoutineParameter can't inherit from CwmColumn (that kludgy approach leads * to strange MDR multiple-inheritance anomalies). And MDR doesn't support * generation of operations, so we can't declare a UML interface with abstract * methods. * *

So, we define this interface outside the model and use proxies to * implement it; see {@link FarragoCatalogUtil#toFemSqltypedElement}. In the * model, we define a placeholder interface {@link FemAbstractTypedElement}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FemSqltypedElement.java#9 $ */ public interface FemSqltypedElement { //~ Methods ---------------------------------------------------------------- /** * @see CwmColumn#getPrecision */ public Integer getPrecision(); /** * @see CwmColumn#setPrecision */ public void setPrecision(Integer newValue); /** * @see CwmColumn#getScale */ public Integer getScale(); /** * @see CwmColumn#setScale */ public void setScale(Integer newValue); /** * @see CwmColumn#getLength */ public Integer getLength(); /** * @see CwmColumn#setLength */ public void setLength(Integer newValue); /** * @see CwmColumn#getCollationName */ public String getCollationName(); /** * @see CwmColumn#setCollationName */ public void setCollationName(String newValue); /** * @see CwmColumn#getCharacterSetName */ public String getCharacterSetName(); /** * @see CwmColumn#setCharacterSetName */ public void setCharacterSetName(String newValue); /** * @see CwmStructuralFeature#getType */ public CwmClassifier getType(); /** * @see CwmStructuralFeature#setType */ public void setType(CwmClassifier newValue); /** * @return unproxied object */ public FemAbstractTypedElement getModelElement(); } // End FemSqltypedElement.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoReposIntegrityErr.java0000444000175000017500000000513511173714170027606 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposIntegrityErr.java#5 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import javax.jmi.reflect.*; /** * FarragoReposIntegrityErr records one integrity error detected by {@link * FarragoRepos#verifyIntegrity}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposIntegrityErr.java#5 $ */ public class FarragoReposIntegrityErr { //~ Instance fields -------------------------------------------------------- private final String description; private final JmiException exception; private final RefObject refObj; //~ Constructors ----------------------------------------------------------- public FarragoReposIntegrityErr( String description, JmiException exception, RefObject refObj) { this.description = description; this.exception = exception; this.refObj = refObj; } //~ Methods ---------------------------------------------------------------- /** * @return description of the error */ public String getDescription() { return description; } /** * @return underlying exception reported by JMI, or null if failed integrity * rule was specific to Farrago */ public JmiException getJmiException() { return exception; } /** * @return object on which error was detected, or null if error is not * specific to an object */ public RefObject getRefObject() { return refObj; } // implement Object public String toString() { return description; } } // End FarragoReposIntegrityErr.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/MockMetadataFactory.java0000444000175000017500000002436211173714170026531 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/MockMetadataFactory.java#15 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.io.*; import java.lang.reflect.*; import java.util.*; import javax.jmi.reflect.*; import net.sf.farrago.fem.fennel.*; import org.eigenbase.jmi.mem.*; import org.eigenbase.util.*; import org.eigenbase.xom.*; /** * Helps create a mock implementation of an MDR metadata factory interface. Mock * implementation of metadata factories which implements the MDR interfaces * using dynamic proxies. Since this implementation does not persist objects, or * even require a repository instance, it is ideal for testing purposes. * *

The name of the class is misleading; it is not itself a metadata factory. * MockMetadataFactory uses dynamic proxies (see {@link Proxy}) to generate the * necessary interfaces on the fly. Inside every proxy is an instance of {@link * org.eigenbase.jmi.mem.JmiMemFactory.ElementImpl}, which stores attributes in * a {@link HashMap} and implements the {@link InvocationHandler} interface * required by the proxy. There are specialized subtypes of * ElementImpl for packages and classes. * *

Since there is no repository to provide metadata, the factory infers the * object model from the Java interfaces: * *

    *
  • Each 'get' method is assumed to be an attribute. *
  • If the return type extends {@link RefClass}, a factory is created when * the object is initialized. *
  • If the return type extends {@link RefPackage}, a sub-package is created * when the object is initialized. *
  • If the return type extends {@link Collection}, a collection attribute is * created. *
  • All other types are presumed to be regular attributes. *
* * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/MockMetadataFactory.java#15 $ */ public abstract class MockMetadataFactory extends JmiMemFactory { //~ Constructors ----------------------------------------------------------- public MockMetadataFactory() { super(); initRelationshipMap(); } //~ Methods ---------------------------------------------------------------- /** * Registers relationships which we want to be maintained as two-way * relationships. This is necessary because we cannot deduce inverse * relationships using Java reflection. * *

Derived classes can add override to define additional relationships. */ protected void initRelationshipMap() { createRelationship( FemExecutionStreamDef.class, "InputFlow", true, FemExecStreamDataFlow.class, "Consumer", false); createRelationship( FemExecutionStreamDef.class, "OutputFlow", true, FemExecStreamDataFlow.class, "Producer", false); } //~ Inner Classes ---------------------------------------------------------- /** * Abstract base class for an iterator over a JMI object and its children. * *

The current implementation isn't very elegant. It makes a lot of * assumptions about how the JMI tree is represented. We should adopt a * 'real' visitor pattern -- with an 'accept' method on each handler object * -- if this class is ever made public. */ static abstract class JmiVisitor { protected void accept(Object o) { List attrNames = new ArrayList(); List attrValues = new ArrayList(); List collectionNames = new ArrayList(); List> collectionValues = new ArrayList>(); List refNames = new ArrayList(); List refValues = new ArrayList(); extractProperties( o, attrNames, attrValues, collectionNames, collectionValues, refNames, refValues); visit( o, attrNames, attrValues, collectionNames, collectionValues, refNames, refValues); } /** * From a data object, builds lists of attributes, collections, and * references. */ protected void extractProperties( Object o, List attrNames, List attrValues, List collectionNames, List> collectionValues, List refNames, List refValues) { Class clazz = o.getClass(); Method [] methods = sortMethods(clazz.getMethods()); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; String methodName = method.getName(); if (methodName.startsWith("get") && (method.getParameterTypes().length == 0) && (method.getDeclaringClass() != Object.class)) { String attrName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4); Class attrClass = method.getReturnType(); Object attrValue; try { attrValue = method.invoke(o, (Object []) null); } catch (IllegalAccessException e) { throw Util.newInternal(e); } catch (InvocationTargetException e) { throw Util.newInternal(e); } if (Collection.class.isAssignableFrom(attrClass)) { collectionNames.add(attrName); collectionValues.add((Collection) attrValue); } else if ( RefBaseObject.class.isAssignableFrom( attrClass)) { refNames.add(attrName); refValues.add((RefBaseObject) attrValue); } else { attrNames.add(attrName); attrValues.add(attrValue); } } } } protected abstract void visit( Object o, List attrNames, List attrValues, List collectionNames, List> collectionValues, List refNames, List refValues); } /** * Formats a JMI object as XML. */ public static class JmiPrinter extends JmiVisitor { // ~ Data members protected final XMLOutput xmlOutput; protected JmiPrinter(PrintWriter pw) { xmlOutput = new XMLOutput(pw); xmlOutput.setGlob(true); } protected void visit( Object o, List attrNames, List attrValues, List collectionNames, List> collectionValues, List refNames, List refValues) { String tagName = getTagName(o); xmlOutput.beginBeginTag(tagName); onElement(o); for (int i = 0; i < attrNames.size(); i++) { String attrName = attrNames.get(i); Object attrValue = attrValues.get(i); onAttribute(attrName, attrValue); } xmlOutput.endBeginTag(tagName); for (int i = 0; i < refNames.size(); i++) { String refName = refNames.get(i); RefBaseObject ref = refValues.get(i); onRef(refName, ref); } for (int i = 0; i < collectionNames.size(); i++) { String collectionName = collectionNames.get(i); List list = (List) collectionValues.get(i); onCollection(collectionName, list); } xmlOutput.endTag(tagName); } protected void onCollection(String collectionName, List list) { xmlOutput.beginTag(collectionName, null); for (int j = 0; j < list.size(); j++) { RefBaseObject ref = (RefBaseObject) list.get(j); accept(ref); } xmlOutput.endTag(collectionName); } protected void onRef(String refName, RefBaseObject ref) { xmlOutput.beginTag(refName, null); accept(ref); xmlOutput.endTag(refName); } protected void onAttribute(String attrName, Object attrValue) { xmlOutput.attribute( attrName, String.valueOf(attrValue)); } protected void onElement(Object o) { } protected String getTagName(Object o) { String className = o.getClass().getInterfaces()[0].getName(); int dot = className.lastIndexOf('.'); String tagName = (dot >= 0) ? className.substring(dot + 1) : className; return tagName; } } } // End MockMetadataFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoSequenceAccessor.java0000444000175000017500000002256311173714170027405 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoSequenceAccessor.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.sql.*; import javax.jmi.reflect.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.resource.*; import org.eigenbase.reltype.*; import org.eigenbase.sql.*; import org.eigenbase.util.*; /** * A FarragoSequenceAccessor optimizes access to sequences. A sequence generates * new values on a per-row basis. But a sequence is not updated after every row * (because that would be very slow.) Instead, an accessor reserves a large * cache of values which it quickly allocates. * *

The accessor synchronizes access so multiple clients can use the sequence * at the same time. However this requires clients to obtain an accessor from * the singleton method FarragoRepos.getSequenceAccessor() * *

To clean up properly after a statement is completed or the database is * shutdown, {@link #unreserve()} should be called to release unused values. * *

Due to the use of singleton sequence accessors, sequence accessors may * exist for a long time. * * @author John Pham * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoSequenceAccessor.java#11 $ */ public class FarragoSequenceAccessor extends CompoundClosableAllocation { //~ Static fields/initializers --------------------------------------------- public static String NEXT_VALUE_METHOD_NAME = "getNext"; private static long MAX_RESERVATION_SIZE = 1000; //~ Instance fields -------------------------------------------------------- private final FarragoRepos repos; private final String mofId; private long increment, min, max; private boolean cycle, ascending; private boolean reserved; private Long nextReservedValue; private long lastReservedValue; //~ Constructors ----------------------------------------------------------- /** * Constructs a FarragoSequenceAccessor * * @param repos the farrago repository containing the sequence * @param sequenceMofId the id of the sequence within the repository */ protected FarragoSequenceAccessor( FarragoRepos repos, String sequenceMofId) { this.repos = repos; mofId = sequenceMofId; FemSequenceGenerator sequence = getSequence(); assert (sequence != null) : "sequence was null"; loadSequence(sequence); } //~ Methods ---------------------------------------------------------------- /** * Initializes the sequence accessor from a sequence. * * @param sequence up to date sequence */ synchronized private void loadSequence(FemSequenceGenerator sequence) { increment = sequence.getIncrement(); min = sequence.getMinValue(); max = sequence.getMaxValue(); cycle = sequence.isCycle(); ascending = (increment > 0); reserved = false; nextReservedValue = null; } /** * Deallocates unused sequence values. */ synchronized public void closeAllocation() { repos.beginReposSession(); try { unreserve(); } finally { repos.endReposSession(); } super.closeAllocation(); } /** * Retrieves a value from the sequence, possibly reserving more values in * the process. * * @return the value retrieved * * @throws EigenbaseException if the sequence has no more values */ synchronized public long getNext() { if (nextReservedValue == null) { reserve(); if (nextReservedValue == null) { throw FarragoResource.instance().SequenceLimitExceeded.ex( getName()); } } long ret = nextReservedValue; if (ret != lastReservedValue) { nextReservedValue += increment; } else { nextReservedValue = null; } return ret; } /** * Modifies a sequence and loads updated fields. * * @param options specifies fields to be modified * @param dataType the data type of the sequence */ synchronized public void alterSequence( FarragoSequenceOptions options, RelDataType dataType) { unreserve(); FarragoReposTxnContext txn = repos.newTxnContext(); try { txn.beginWriteTxn(); FemSequenceGenerator sequence = getSequence(); assert (sequence != null) : "sequence was null"; options.alter(sequence, dataType); loadSequence(sequence); txn.commit(); } finally { txn.rollback(); } } /** * Reserves up to {@link #MAX_RESERVATION_SIZE} values in the sequence. * Updates the baseValue of a sequence in the catalog sequence to the first * valid unreserved value. * *

If the reservation was successful, then {@link #nextReservedValue} * will be set to a non-null value. */ synchronized private void reserve() { // Do nothing if values remain in current reservation if (nextReservedValue != null) { return; } FarragoReposTxnContext txn = repos.newTxnContext(); try { txn.beginWriteTxn(); reserveInternal(); txn.commit(); } finally { // REVIEW jvs 12-Jan-2007: need to revert transient state // in this class too? txn.rollback(); } } synchronized private void reserveInternal() { assert (nextReservedValue == null); FemSequenceGenerator sequence = getSequence(); assert (sequence != null) : "sequence was null"; if (sequence.isExpired()) { return; } // Find the number of values to reserve, for example: // currentBase=0, 1, 2, ..., incrementCount long currentBase = sequence.getBaseValue(); long diff = ascending ? (max - currentBase) : (min - currentBase); long incrementCount = diff / increment; long reservation = Math.min(incrementCount + 1, MAX_RESERVATION_SIZE); nextReservedValue = currentBase; if (reservation == (incrementCount + 1)) { // need to cycle if (cycle) { long first = ascending ? min : max; sequence.setBaseValue(first); } else { long lastValid = nextReservedValue + (incrementCount * increment); sequence.setBaseValue(lastValid); sequence.setExpired(true); } } else { long nextValid = nextReservedValue + (reservation * increment); sequence.setBaseValue(nextValid); } lastReservedValue = nextReservedValue + ((reservation - 1) * increment); reserved = true; } /** * Returns values unused by the sequence accessor to the catalog */ synchronized private void unreserve() { if (!reserved) { return; } FarragoReposTxnContext txn = repos.newTxnContext(); try { txn.beginWriteTxn(); FemSequenceGenerator sequence = getSequence(); if (sequence == null) { // NOTE: sequence was deleted } else if (nextReservedValue == null) { // No values to deallocate } else { sequence.setBaseValue(nextReservedValue); nextReservedValue = null; sequence.setExpired(false); } reserved = false; txn.commit(); } finally { txn.rollback(); } } /** * Retrieves the underlying sequence from the catalog * * @return the underlying sequence, or null if the sequence was deleted */ synchronized private FemSequenceGenerator getSequence() { RefBaseObject o = repos.getMdrRepos().getByMofId(mofId); return (FemSequenceGenerator) o; } /** * Returns the name of the sequence */ private String getName() { FemSequenceGenerator sequence = getSequence(); assert (sequence != null) : "sequence was null"; if (sequence.getName().length() > 0) { return sequence.getName(); } SqlIdentifier tableName = FarragoCatalogUtil.getQualifiedName( sequence.getColumn().getOwner()); return tableName.toString(); } } // End FarragoSequenceAccessor.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoCatalogInit.java0000444000175000017500000001264511173714170026350 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoCatalogInit.java#26 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import net.sf.farrago.fem.security.*; import net.sf.farrago.fem.sql2003.*; /** * FarragoCatalogInit contains one-time persistent initialization procedures for * the Farrago catalog. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoCatalogInit.java#26 $ */ public class FarragoCatalogInit extends FarragoAbstractCatalogInit { //~ Static fields/initializers --------------------------------------------- /** * Reserved name for the system boot catalog. */ public static final String SYSBOOT_CATALOG_NAME = "SYS_BOOT"; /** * Reserved name for the local catalog. */ public static final String LOCALDB_CATALOG_NAME = "LOCALDB"; /** * Reserved name for the public role. */ public static final String PUBLIC_ROLE_NAME = "PUBLIC"; /** * Reserved name for the system admin authorization user. Note that this is * intentionally lower-case to match the SQL Server convention. */ public static final String SA_USER_NAME = "sa"; /** * Default jdbc connection timeout in milliseconds */ public static final long DEFAULT_CONNECTION_TIMEOUT_MILLIS = 86400000; /** * Default freshmen page queue percentage */ public static final int DEFAULT_FRESHMEN_PAGE_QUEUE_PERCENTAGE = 25; /** * Default page history queue percentage */ public static final int DEFAULT_PAGE_HISTORY_QUEUE_PERCENTAGE = 100; /** * Default maximum number of pages to prefetch */ public static final int DEFAULT_PREFETCH_PAGES_MAX = 12; /** * Default prefetch throttle rate */ public static final int DEFAULT_PREFETCH_THROTTLE_RATE = 10; //~ Constructors ----------------------------------------------------------- protected FarragoCatalogInit(FarragoRepos repos) { super(repos); } //~ Methods ---------------------------------------------------------------- /** * Creates objects owned by the system. This is only done once during * database creation. * * @param repos the repository in which to initialize the catalog */ public static void createSystemObjects(FarragoRepos repos) { tracer.info("Creating system-owned catalog objects"); FarragoCatalogInit init = null; FarragoReposTxnContext txn = repos.newTxnContext(); boolean rollback = true; try { try { txn.beginWriteTxn(); init = new FarragoCatalogInit(repos); init.initCatalog(); rollback = false; } finally { if (init != null) { // Guarantee that publishObjects is called init.publishObjects(rollback); } } } finally { // Guarantee that the txn is cleaned up if (rollback) { txn.rollback(); } else { txn.commit(); } } tracer.info("Creation of system-owned catalog objects committed"); } private void initCatalog() { createSystemCatalogs(); createSystemAuth(); // NOTE jvs 3-Jan-2007: system types are created by the UDR // sys_boot.sys_boot.update_system_objects(), but we do it // here redundantly to support Farrago extension projects // which rely on FarragoCatalogInit to do all the work. updateSystemTypes(); } private void createSystemCatalogs() { FemLocalCatalog catalog; catalog = repos.newFemLocalCatalog(); catalog.setName(SYSBOOT_CATALOG_NAME); FarragoCatalogUtil.initializeCatalog(repos, catalog); catalog = repos.newFemLocalCatalog(); catalog.setName(LOCALDB_CATALOG_NAME); FarragoCatalogUtil.initializeCatalog(repos, catalog); } private void createSystemAuth() { // Create the System Internal User FemUser systemUser = repos.newFemUser(); systemUser.setName(SYSTEM_USER_NAME); // Create the System admin user, this is the only system created // authenticatable user (via login) FemUser saUser = repos.newFemUser(); saUser.setName(SA_USER_NAME); // Create the built-in role PUBLIC FemRole publicRole = repos.newFemRole(); publicRole.setName(PUBLIC_ROLE_NAME); } } // End FarragoCatalogInit.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoReposTxnContext.java0000444000175000017500000001744711173714170027306 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposTxnContext.java#19 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import net.sf.farrago.resource.*; /** * FarragoReposTxnContext manages the state of at most one repository * transaction. A context may be inactive, meaning it has no current * transaction. * *

Always use the following exception-safe transaction pattern: * *


 *   FarragoReposTxnContext txn = repos.newTxnContext();
 *   try {
 *       txn.beginWriteTxn();
 *       ... do stuff which accesses repository ...
 *       txn.commit();
 *   } finally {
 *       // no effect if already committed or beginWriteTxn failed
 *       txn.rollback();
 *   }
 *
* * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposTxnContext.java#19 $ */ public class FarragoReposTxnContext { //~ Enums ------------------------------------------------------------------ private enum State { NO_TXN, READ_TXN, WRITE_TXN } //~ Instance fields -------------------------------------------------------- private FarragoRepos repos; private State state; private int lockLevel; private final boolean manageReposSession; private boolean readOnly; //~ Constructors ----------------------------------------------------------- /** * Creates a new inactive transaction context with manual repository session * management. * * @param repos the repos against which transactions are to be performed */ public FarragoReposTxnContext(FarragoRepos repos) { this(repos, false); } /** * Creates a new inactive transaction context. * * @param repos the repos against which transactions are to be performed * @param manageRepoSession if true, a repository session is wrapped around * each transaction */ public FarragoReposTxnContext( FarragoRepos repos, boolean manageRepoSession) { this(repos, manageRepoSession, false); } /** * Creates a new inactive transaction context that's optionally readonly. * * @param repos the repos against which transactions are to be performed * @param manageRepoSession if true, a repository session is wrapped around * each transaction */ public FarragoReposTxnContext( FarragoRepos repos, boolean manageRepoSession, boolean readOnly) { this.repos = repos; state = State.NO_TXN; lockLevel = 0; this.manageReposSession = manageRepoSession; this.readOnly = readOnly; } //~ Methods ---------------------------------------------------------------- /** * @return whether a transaction is currently in progress */ public boolean isTxnInProgress() { return state != State.NO_TXN; } /** * @return whether a read-only transaction is currently in progress */ public boolean isReadTxnInProgress() { return state == State.READ_TXN; } /** * Begins a new read-only transaction. */ public void beginReadTxn() { assert (!isTxnInProgress()); if (manageReposSession) { repos.beginReposSession(); } repos.beginReposTxn(false); state = State.READ_TXN; } /** * Begins a new read/write transaction. */ public void beginWriteTxn() { assert (!isTxnInProgress()); if (readOnly) { throw FarragoResource.instance().CatalogReadOnly.ex(); } if (manageReposSession) { repos.beginReposSession(); } // NOTE jvs 12-Jan-2007: don't change state until AFTER successfully // beginning a transaction; if beginReposTxn throws an excn, // we want to stay in State.NO_TXN repos.beginReposTxn(true); state = State.WRITE_TXN; } /** * Commits the active transaction, if any. */ public void commit() { if (!isTxnInProgress()) { return; } // NOTE jvs 12-Jan-2007: change state BEFORE attempting // to end transaction; if endReposTxn throws an excn, // we're in an unknown state, but further calls could just // mask the original excn, so pretend we're back to // State.NO_TXN regardless. state = State.NO_TXN; repos.endReposTxn(false); if (manageReposSession) { repos.endReposSession(); } } /** * Rolls back the active transaction, if any. */ public void rollback() { if (!isTxnInProgress()) { return; } // NOTE jvs 12-Jan-2007: see comment in commit() for ordering rationale state = State.NO_TXN; repos.endReposTxn(true); if (manageReposSession) { repos.endReposSession(); } } /** * Acquires a repository lock and begins a matching MDR transaction (shared * lock for read, or exclusive lock for write). Typical usage is start of * SQL statement preparation (e.g. readOnly=true for DML or query, false for * DDL). * * @param readOnly if true, a shared lock is acquired on the catalog; * otherwise, an exclusive lock is acquired */ public void beginLockedTxn(boolean readOnly) { int level = (readOnly) ? 1 : 2; // TODO jvs 24-Jan-2007: Get rid of downcast here and below by // making all creation of FarragoReposTxnContext go through // factory method interface on FarragoRepos. ((FarragoReposImpl) repos).lockRepos(level); // Don't set lockLevel until we've successfully acquired the lock lockLevel = level; if (readOnly) { beginReadTxn(); } else { beginWriteTxn(); } } /** * Releases lock acquired by beginLockedTxn. Caller should already have * ended transaction with either commit or rollback. */ public void unlockAfterTxn() { if (lockLevel != 0) { ((FarragoReposImpl) repos).unlockRepos(lockLevel); lockLevel = 0; } } /** * Puts the repository in exclusive access mode. When in this mode, * subsequent attempts to lock the repository will return an exception * immediately rather than wait for a required repository lock to become * available. */ public void beginExclusiveAccess() { ((FarragoReposImpl) repos).beginExclusiveAccess(); } /** * Ends exclusive access mode for the repository. */ public void endExclusiveAccess() { ((FarragoReposImpl) repos).endExclusiveAccess(); } /** * Switches the repository to read-only mode. */ public void setReposReadOnly() { readOnly = true; } } // End FarragoReposTxnContext.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoAbstractCatalogInit.java0000444000175000017500000004023411173714170030027 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoAbstractCatalogInit.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.sql.*; import java.util.*; import java.util.logging.*; import javax.jmi.reflect.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.datatypes.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.resource.*; import net.sf.farrago.trace.*; import org.eigenbase.jmi.*; import org.eigenbase.sql.type.*; import org.netbeans.api.mdr.events.*; /** * FarragoAbstractCatalogInit provides an abstract base class for classes that * initialize the Farrago catalog. * * @author Zelaine Fong * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoAbstractCatalogInit.java#11 $ */ public abstract class FarragoAbstractCatalogInit implements MDRPreChangeListener { //~ Static fields/initializers --------------------------------------------- // ~ Static fields/initializers ------------------------------------------- protected static final Logger tracer = FarragoTrace.getReposTracer(); /** * Reserved name for the system internal authorization user. */ public static final String SYSTEM_USER_NAME = "_SYSTEM"; //~ Instance fields -------------------------------------------------------- protected final FarragoRepos repos; private final Set objs; private final String timestamp; //~ Constructors ----------------------------------------------------------- protected FarragoAbstractCatalogInit(FarragoRepos repos) { this.repos = repos; objs = new HashSet(); // listen to MDR events during initialization so that we can // consistently fill in generic information on all objects repos.getMdrRepos().addListener( this, AttributeEvent.EVENTMASK_ATTRIBUTE); timestamp = FarragoCatalogUtil.createTimestamp(); } //~ Methods ---------------------------------------------------------------- // implement MDRChangeListener public void change(MDRChangeEvent event) { // don't care } // implement MDRPreChangeListener public void changeCancelled(MDRChangeEvent event) { // don't care } // implement MDRPreChangeListener public void plannedChange(MDRChangeEvent event) { if (event instanceof AttributeEvent) { objs.add(event.getSource()); } } protected void publishObjects(boolean rollback) { repos.getMdrRepos().removeListener(this); if (rollback) { return; } for (Object obj : objs) { if (obj instanceof CwmModelElement) { CwmModelElement modelElement = (CwmModelElement) obj; // Set visibility so that DdlValidator doesn't try // to revalidate this object. modelElement.setVisibility(VisibilityKindEnum.VK_PUBLIC); // Define this as a system-owned object. FemGrant grant = FarragoCatalogUtil.newCreationGrant( repos, SYSTEM_USER_NAME, SYSTEM_USER_NAME, modelElement); JmiObjUtil.setMandatoryPrimitiveDefaults(grant); } if (obj instanceof FemAnnotatedElement) { FemAnnotatedElement annotatedElement = (FemAnnotatedElement) obj; if (annotatedElement.getDescription() == null) { annotatedElement.setDescription( FarragoResource.instance() .CatalogBootstrapObjDescription.str()); } FarragoCatalogUtil.updateAnnotatedElement( annotatedElement, timestamp, true); } JmiObjUtil.setMandatoryPrimitiveDefaults((RefObject) obj); } } protected void defineTypeAlias(String aliasName, CwmSqldataType type) { CwmTypeAlias typeAlias = repos.newCwmTypeAlias(); typeAlias.setName(aliasName); typeAlias.setType(type); } protected void updateSystemParameters() { // If migrated from a catalog version where these parameters // don't exist, they will be set to null; so set them to default // values. // // NOTE zfong 5/22/08 - Make sure to also update // {@link FarragoTestCase#saveParameters(FarragoRepos) to avoid // resetting these parameters to their original null values. FemFarragoConfig config = repos.getCurrentConfig(); if (config.getConnectionTimeoutMillis() == null) { config.setConnectionTimeoutMillis( new Long(FarragoCatalogInit.DEFAULT_CONNECTION_TIMEOUT_MILLIS)); } if (repos.isFennelEnabled()) { FemFennelConfig fennelConfig = config.getFennelConfig(); if (fennelConfig.getFreshmenPageQueuePercentage() == null) { fennelConfig.setFreshmenPageQueuePercentage( new Integer( FarragoCatalogInit .DEFAULT_FRESHMEN_PAGE_QUEUE_PERCENTAGE)); } if (fennelConfig.getPageHistoryQueuePercentage() == null) { fennelConfig.setPageHistoryQueuePercentage( new Integer( FarragoCatalogInit.DEFAULT_PAGE_HISTORY_QUEUE_PERCENTAGE)); } if (fennelConfig.getPrefetchPagesMax() == null) { fennelConfig.setPrefetchPagesMax( new Integer(FarragoCatalogInit.DEFAULT_PREFETCH_PAGES_MAX)); } if (fennelConfig.getPrefetchThrottleRate() == null) { fennelConfig.setPrefetchThrottleRate( new Integer( FarragoCatalogInit.DEFAULT_PREFETCH_THROTTLE_RATE)); } if (fennelConfig.getDeviceSchedulerType() == null) { fennelConfig.setDeviceSchedulerType( DeviceSchedulerTypeEnum.DEFAULT); } } } protected void updateSystemTypes() { Collection types = repos.allOfClass(CwmSqlsimpleType.class); CwmSqlsimpleType simpleType; simpleType = FarragoCatalogUtil.getModelElementByName(types, "BOOLEAN"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("BOOLEAN"); simpleType.setTypeNumber(Types.BOOLEAN); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "TINYINT"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("TINYINT"); simpleType.setTypeNumber(Types.TINYINT); simpleType.setNumericPrecision(8); simpleType.setNumericPrecisionRadix(2); simpleType.setNumericScale(0); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "SMALLINT"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("SMALLINT"); simpleType.setTypeNumber(Types.SMALLINT); simpleType.setNumericPrecision(16); simpleType.setNumericPrecisionRadix(2); simpleType.setNumericScale(0); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "INTEGER"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("INTEGER"); simpleType.setTypeNumber(Types.INTEGER); simpleType.setNumericPrecision(32); simpleType.setNumericPrecisionRadix(2); simpleType.setNumericScale(0); defineTypeAlias("INT", simpleType); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "BIGINT"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("BIGINT"); simpleType.setTypeNumber(Types.BIGINT); simpleType.setNumericPrecision(64); simpleType.setNumericPrecisionRadix(2); simpleType.setNumericScale(0); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "REAL"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("REAL"); simpleType.setTypeNumber(Types.REAL); simpleType.setNumericPrecision(23); simpleType.setNumericPrecisionRadix(2); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "DOUBLE"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("DOUBLE"); simpleType.setTypeNumber(Types.DOUBLE); simpleType.setNumericPrecision(52); simpleType.setNumericPrecisionRadix(2); defineTypeAlias("DOUBLE PRECISION", simpleType); defineTypeAlias("FLOAT", simpleType); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "VARCHAR"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("VARCHAR"); simpleType.setTypeNumber(Types.VARCHAR); // NOTE: this is an upper bound based on usage of 2-byte length // indicators in stored tuples; there are further limits based on // page size (imposed during table creation) simpleType.setCharacterMaximumLength(65535); defineTypeAlias("CHARACTER VARYING", simpleType); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "VARBINARY"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("VARBINARY"); simpleType.setTypeNumber(Types.VARBINARY); simpleType.setCharacterMaximumLength(65535); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "CHAR"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("CHAR"); simpleType.setTypeNumber(Types.CHAR); simpleType.setCharacterMaximumLength(65535); defineTypeAlias("CHARACTER", simpleType); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "BINARY"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("BINARY"); simpleType.setTypeNumber(Types.BINARY); simpleType.setCharacterMaximumLength(65535); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "DATE"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("DATE"); simpleType.setTypeNumber(Types.DATE); simpleType.setDateTimePrecision(0); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "TIME"); if (simpleType == null) { // TODO jvs 26-July-2004: Support fractional precision for TIME and // TIMESTAMP. Currently, most of the support is there for up to // milliseconds, but JDBC getString conversion is missing (see // comments in SqlDateTimeWithoutTZ). SQL99 says default precision // for TIMESTAMP is microseconds, so some more work is required to // support that. Default precision for TIME is seconds, which is // already the case. simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("TIME"); simpleType.setTypeNumber(Types.TIME); simpleType.setDateTimePrecision(0); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "TIMESTAMP"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("TIMESTAMP"); simpleType.setTypeNumber(Types.TIMESTAMP); simpleType.setDateTimePrecision(0); } simpleType = FarragoCatalogUtil.getModelElementByName(types, "DECIMAL"); if (simpleType == null) { simpleType = repos.newCwmSqlsimpleType(); simpleType.setName("DECIMAL"); simpleType.setTypeNumber(Types.DECIMAL); simpleType.setNumericPrecision(SqlTypeName.MAX_NUMERIC_PRECISION); simpleType.setNumericPrecisionRadix(10); simpleType.setNumericScale(SqlTypeName.MAX_NUMERIC_SCALE); defineTypeAlias("DEC", simpleType); } Collection structTypes = repos.allOfClass(CwmSqlstructuredType.class); CwmSqlstructuredType structType; structType = FarragoCatalogUtil.getModelElementByName(structTypes, "CURSOR"); if (structType == null) { // placeholder for CURSOR parameters to UDX's; by adding // an "eponymous alias", we'll make it visible from type lookup; // we don't use a simple type here because we don't want it to // show up as part of standard type info CwmSqlstructuredType cursorType = repos.newCwmSqlstructuredType(); cursorType.setName("CURSOR"); cursorType.setTypeNumber(SqlTypeName.CURSOR.getJdbcOrdinal()); defineTypeAlias("CURSOR", cursorType); } structType = FarragoCatalogUtil.getModelElementByName( structTypes, "COLUMN_LIST"); if (structType == null) { // NOTE jvs 27-Dec-2006: like CURSOR, need an eponymous alias for // COLUMN_LIST; this is annoying, because it's entirely an internal // type name (users are never supposed to reference it // explicitly--they use SELECT FROM syntax instead); but without // it, type resolution fails internally; there's probably // some way to fix this CwmSqlstructuredType columnListType = repos.newCwmSqlstructuredType(); columnListType.setName("COLUMN_LIST"); columnListType.setTypeNumber( SqlTypeName.COLUMN_LIST.getJdbcOrdinal()); defineTypeAlias("COLUMN_LIST", columnListType); } Collection multisetTypes = repos.allOfClass(FemSqlmultisetType.class); FemSqlmultisetType multisetType; multisetType = FarragoCatalogUtil.getModelElementByName(multisetTypes, "MULTISET"); if (multisetType == null) { // REVIEW jvs 11-Aug-2005: This isn't a real type descriptor, since // collection types are constructed anonymously rather than defined // as named instances. Do we need it? FemSqlcollectionType collectType; collectType = repos.newFemSqlmultisetType(); collectType.setName("MULTISET"); // a multiset has the same type# as an array for now collectType.setTypeNumber(Types.ARRAY); } } } // End FarragoAbstractCatalogInit.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoReposImpl.java0000444000175000017500000005306011173714170026060 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposImpl.java#31 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.util.*; import java.util.concurrent.locks.*; import java.util.logging.*; import javax.jmi.model.*; import javax.jmi.reflect.*; import net.sf.farrago.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.resource.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.eigenbase.util.*; /** * Implementation of {@link FarragoRepos} using a MDR repository. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposImpl.java#31 $ */ public abstract class FarragoReposImpl extends FarragoMetadataFactoryImpl implements FarragoRepos { //~ Static fields/initializers --------------------------------------------- private static final Logger tracer = FarragoTrace.getReposTracer(); /** * TODO: look this up from repository */ private static final int maxNameLength = 128; //~ Instance fields -------------------------------------------------------- private boolean isFennelEnabled; protected final FarragoCompoundAllocation allocations = new FarragoCompoundAllocation(); private final Map localizedClassNames = new HashMap(); private final List resourceBundles = new ArrayList(); private JmiModelGraph modelGraph; private JmiModelView modelView; private final Map sequenceMap; private final ReentrantReadWriteLock sxLock = new ReentrantReadWriteLock(); private ThreadLocal cache; private Boolean exclusiveAccess; //~ Constructors ----------------------------------------------------------- /** * Opens a Farrago repository. * * @param owner Allocation owner */ public FarragoReposImpl( FarragoAllocationOwner owner) { owner.addAllocation(this); sequenceMap = new HashMap(); cache = new ThreadLocal() { @Override protected ReposCache initialValue() { return new ReposCache(); } }; exclusiveAccess = false; } //~ Methods ---------------------------------------------------------------- // TODO jvs 30-Nov-2005: rename these methods; initGraph initializes // other stuff besides the model graph /** * Initializes the model graph. The constructor of a concrete subclass must * call this after the repository has been initialized, and {@link * #getRootPackage()} is available. */ protected void initGraph() { isFennelEnabled = !getDefaultConfig().isFennelDisabled(); initGraphOnly(); } protected void initGraphOnly() { // TODO: SWZ: 2008-03-27: Obtain the classloader from // EnkiMDRepository.getDefaultClassLoader(). ClassLoader classLoader = MDRepositoryFactory.getDefaultClassLoader(); modelGraph = new JmiModelGraph( getRootPackage(), classLoader, true); modelView = new JmiModelView(modelGraph); } protected FemFarragoConfig getDefaultConfig() { // TODO: multiple named configurations. For now, build should have // imported exactly one configuration named Current. Collection configs = (Collection) getConfigPackage() .getFemFarragoConfig().refAllOfClass(); assert (configs.size() == 1); FemFarragoConfig defaultConfig = configs.iterator().next(); assert (defaultConfig.getName().equals("Current")); return defaultConfig; } protected static String getLocalizedClassKey(RefClass refClass) { String className = refClass.refMetaObject().refGetValue("name").toString(); return "Uml" + className; } // implement FarragoRepos public JmiModelGraph getModelGraph() { return modelGraph; } // implement FarragoRepos public JmiModelView getModelView() { return modelView; } // implement FarragoRepos public CwmCatalog getSelfAsCatalog() { return getCatalog(FarragoCatalogInit.LOCALDB_CATALOG_NAME); } // implement FarragoRepos public int getIdentifierPrecision() { return maxNameLength; } // implement FarragoRepos public String getDefaultCharsetName() { // REVIEW jvs 21-Jan-2009: Do we really want an implicit // session here? beginReposSession(); try { CwmCatalog catalog = getSelfAsCatalog(); if (catalog == null) { return SaffronProperties.instance().defaultCharset.get(); } else { return catalog.getDefaultCharacterSetName(); } } finally { endReposSession(); } } // implement FarragoRepos public String getDefaultCollationName() { beginReposSession(); try { CwmCatalog catalog = getSelfAsCatalog(); if (catalog == null) { return SaffronProperties.instance().defaultCollation.get(); } else { return catalog.getDefaultCollationName(); } } finally { endReposSession(); } } // implement FarragoRepos public boolean isFennelEnabled() { return isFennelEnabled; } // implement FarragoRepos public String getLocalizedObjectName( CwmModelElement modelElement) { return getLocalizedObjectName( modelElement, modelElement.refClass()); } // implement FarragoRepos public String getLocalizedObjectName( String name) { return getLocalizedObjectName(null, name, null); } // implement FarragoRepos public String getLocalizedObjectName( CwmModelElement modelElement, RefClass refClass) { String qualifierName = null; CwmNamespace namespace = modelElement.getNamespace(); if (namespace != null) { qualifierName = namespace.getName(); } return getLocalizedObjectName( qualifierName, modelElement.getName(), refClass); } // implement FarragoRepos public String getLocalizedObjectName( String qualifierName, String objectName, RefClass refClass) { StringBuilder sb = new StringBuilder(); // TODO: escaping if (refClass != null) { sb.append(getLocalizedClassName(refClass)); sb.append(" "); } if (qualifierName != null) { sb.append("\""); sb.append(qualifierName); sb.append("\"."); } sb.append("\""); sb.append(objectName); sb.append("\""); return sb.toString(); } // implement FarragoRepos public String getLocalizedClassName(RefClass refClass) { String umlKey = getLocalizedClassKey(refClass); String name = localizedClassNames.get(umlKey); if (name != null) { return name; } else { // NOTE jvs 12-Jan-2005: we intentionally return something // nasty so that if it shows up in user-level error messages, // someone nice will maybe log a bug and get it fixed return "NOT_YET_LOCALIZED_" + umlKey; } } // implement FarragoRepos public CwmCatalog getCatalog(String catalogName) { Map> catalogCache = cache.get().catalogCache; Pair catalogDesc = catalogCache.get(catalogName); CwmCatalog catalog; if (catalogDesc != null) { catalog = (CwmCatalog) getEnkiMdrRepos().getByMofId( catalogDesc.right, catalogDesc.left); } else { catalog = FarragoCatalogUtil.getModelElementByName( allOfType(CwmCatalog.class), catalogName); if (catalog != null) { catalogDesc = new Pair( catalog.refClass(), catalog.refMofId()); catalogCache.put(catalogName, catalogDesc); } } return catalog; } // implement FarragoRepos public FemTagAnnotation getTagAnnotation( FemAnnotatedElement element, String tagName) { for (FemTagAnnotation tag : element.getTagAnnotation()) { if (tag.getName().equals(tagName)) { return tag; } } return null; } // implement FarragoRepos public void setTagAnnotationValue( FemAnnotatedElement element, String tagName, String tagValue) { FemTagAnnotation tag = getTagAnnotation(element, tagName); if (tag == null) { tag = newFemTagAnnotation(); tag.setName(tagName); element.getTagAnnotation().add(tag); } tag.setValue(tagValue); } // implement FarragoRepos public String getTagAnnotationValue( FemAnnotatedElement element, String tagName) { FemTagAnnotation tag = getTagAnnotation(element, tagName); if (tag == null) { return null; } else { return tag.getValue(); } } // implement FarragoRepos public CwmTaggedValue getTag( CwmModelElement element, String tagName) { Collection tags = getCorePackage().getTaggedElement().getTaggedValue(element); for (Object o : tags) { CwmTaggedValue tag = (CwmTaggedValue) o; if (tag.getTag().equals(tagName)) { return tag; } } return null; } // implement FarragoRepos public void setTagValue( CwmModelElement element, String tagName, String tagValue) { CwmTaggedValue tag = getTag(element, tagName); if (tag == null) { tag = newCwmTaggedValue(); tag.setTag(tagName); getCorePackage().getTaggedElement().add(element, tag); } tag.setValue(tagValue); } // implement FarragoRepos public String getTagValue( CwmModelElement element, String tagName) { CwmTaggedValue tag = getTag(element, tagName); if (tag == null) { return null; } else { return tag.getValue(); } } // implement FarragoRepos public List verifyIntegrity( RefObject refObj) { Collection exceptions; if (refObj == null) { return verifyIntegrityAll(); } else if (refObj instanceof CwmDependency) { // REVIEW jvs 3-Sept-2006: CwmDependency does not allow // for dangling dependencies, but we rely on those, so // skip them for now. exceptions = null; } else { exceptions = refObj.refVerifyConstraints(false); } if (exceptions == null) { return Collections.emptyList(); } List errs = new ArrayList(); for (Object obj : exceptions) { JmiException ex = (JmiException) obj; String description = ex.getClass().getName(); if (ex.getMessage() != null) { description += ": " + ex.getMessage(); } RefObject metaObj = ex.getElementInError(); if (metaObj != null) { description += ", "; description += ReflectUtil.getUnqualifiedClassName(metaObj.getClass()); description += " = "; if (metaObj instanceof ModelElement) { description += ((ModelElement) metaObj).getName(); } else if (metaObj instanceof CwmModelElement) { description += ((CwmModelElement) metaObj).getName(); } else { description += metaObj; } } if (ex.getObjectInError() != null) { description += ", extra = " + ex.getObjectInError(); } if (refObj != null) { RefClass refClass = refObj.refClass(); String className = JmiObjUtil.getMetaObjectName(refClass); String objectName = null; try { // If it has a name attribute, use that objectName = (String) refObj.refGetValue("name"); } catch (Throwable t) { // Otherwise, fall through to dump below. } if (objectName == null) { objectName = refObj.toString(); } description += ", " + className; description += " = " + objectName; } FarragoReposIntegrityErr err = new FarragoReposIntegrityErr(description, ex, refObj); errs.add(err); } return errs; } private List verifyIntegrityAll() { List errs = new ArrayList(); for (JmiClassVertex classVertex : modelGraph.vertexSet()) { RefClass refClass = classVertex.getRefClass(); for (Object obj : refClass.refAllOfClass()) { RefObject refObj = (RefObject) obj; errs.addAll(verifyIntegrity(refObj)); } } return errs; } // implement FarragoRepos public void addResourceBundles(List bundles) { resourceBundles.addAll(bundles); Iterator iter = bundles.iterator(); for (ResourceBundle resourceBundle : bundles) { Enumeration e = resourceBundle.getKeys(); while (e.hasMoreElements()) { // NOTE jvs 12-Apr-2005: This early binding won't // work once we have sessions with different locales, but // I'll leave that for someone wiser in the ways of i18n. String key = e.nextElement(); if (key.startsWith("Uml")) { localizedClassNames.put( key, resourceBundle.getString(key)); } } } } public Object getMetadataFactory(String prefix) { if (prefix.equals("Fem")) { return (FarragoMetadataFactory) this; } throw Util.newInternal("Unknown metadata factory '" + prefix + "'"); } public FarragoSequenceAccessor getSequenceAccessor( String mofId) { synchronized (sequenceMap) { FarragoSequenceAccessor sequence = sequenceMap.get(mofId); if (sequence != null) { return sequence; } sequence = new FarragoSequenceAccessor(this, mofId); allocations.addAllocation(sequence); sequenceMap.put(mofId, sequence); return sequence; } } public String expandProperties(String value) { return FarragoProperties.instance().expandProperties(value); } private RefClass findRefClass(Class clazz) { JmiClassVertex vertex = modelGraph.getVertexForJavaInterface(clazz); return vertex.getRefClass(); } public Collection allOfClass(Class clazz) { RefClass refClass = findRefClass(clazz); return (Collection) refClass.refAllOfClass(); } public Collection allOfType(Class clazz) { RefClass refClass = findRefClass(clazz); return (Collection) refClass.refAllOfType(); } // implement FarragoRepos public FarragoModelLoader getModelLoader() { return null; } // implement FarragoRepos public FarragoReposTxnContext newTxnContext() { return newTxnContext(false); } // implement FarragoRepos public FarragoReposTxnContext newTxnContext(boolean manageReposSession) { return new FarragoReposTxnContext(this, manageReposSession); } /** * Places either a shared or exclusive lock on the repository. Multiple * shared locks are allowed from different threads when no thread holds an * exclusive lock, but only one thread can hold an exclusive lock at a time, * preventing shared locks from other threads. If a conflicting lock is * requested, that requester will wait until the requested lock is * available. Locks are reentrant: a thread can take the same lock more than * once, but must make a matching number of calls to {@link #unlockRepos} in * order to release the lock. Upgrade and downgrade are not supported. * *

This lock is independent of MDR transaction state (i.e. it can be held * even when no MDR transaction is in progress; an MDR transaction can be * started without taking this lock; and an exclusive lock can be taken even * for a read-only MDR transaction). Currently, its only public exposure is * via {@link FarragoReposTxnContext}, which matches shared with read and * exclusive with write. * * @param lockLevel 1 for a shared lock, 2 for an exclusive lock */ public void lockRepos(int lockLevel) { synchronized (exclusiveAccess) { if (exclusiveAccess.booleanValue()) { throw FarragoResource.instance().NeedExclusiveAccess.ex(); } } if (lockLevel == 1) { sxLock.readLock().lock(); } else if (lockLevel == 2) { sxLock.writeLock().lock(); } else { assert (false); } } /** * Releases either a shared or exclusive lock on the repository that was * previously acquired (caller must ensure consistency). * * @param lockLevel 1 for a shared lock, 2 for an exclusive lock */ public void unlockRepos(int lockLevel) { if (lockLevel == 1) { sxLock.readLock().unlock(); } else if (lockLevel == 2) { sxLock.writeLock().unlock(); } else { assert (false); } } // TODO: SWZ: 2008-03-27: implement on platform side and remove // implement FarragoRepos (for red-zone components ignorant of Enki) public EnkiMDRepository getEnkiMdrRepos() { return (EnkiMDRepository) getMdrRepos(); } // TODO: SWZ: 2008-03-27: implement on platform side and call this public void beginReposSession() { cache.get().beginSession(); } // TODO: SWZ: 2008-03-27: implement on platform side and call this public void endReposSession() { cache.get().endSession(); } /** * Puts the repository in exclusive access mode. When in this mode, * subsequent attempts to lock the repository will return an exception * immediately rather than wait for a required repository lock to become * available. */ public void beginExclusiveAccess() { synchronized (exclusiveAccess) { if (exclusiveAccess.booleanValue()) { throw FarragoResource.instance().NeedExclusiveAccess.ex(); } exclusiveAccess = true; } } /** * Ends exclusive access mode for the repository. */ public void endExclusiveAccess() { synchronized (exclusiveAccess) { exclusiveAccess = false; } } //~ Inner Classes ---------------------------------------------------------- private static class ReposCache { protected int sessionDepth; protected Map> catalogCache; private ReposCache() { this.sessionDepth = 0; } private void beginSession() { if (sessionDepth++ == 0) { catalogCache = new HashMap>(); } } protected void endSession() { if (--sessionDepth == 0) { catalogCache.clear(); } } } } // End FarragoReposImpl.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoColumnHistogram.java0000444000175000017500000005403011173714170027257 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoColumnHistogram.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.sql.*; import java.util.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.fem.sql2003.*; import org.eigenbase.rex.*; import org.eigenbase.sarg.*; import org.eigenbase.stat.*; import org.eigenbase.util14.*; /** * FarragoColumnHistogram reads and interprets statistics for a column of a * Farrago column set. An instance of this class is returned to summarize the * result of applying predicate(s) to a column. * *

TODO: Review statistics analysis for handling of null semantics. Null * values are less than all other values (e.g. bars might contain the starting * values null,0,1,...). Because stats analysis is based on ranges, only ranges * which include consecutive bars are supported. Examples: * *

    *
  • if NULL_MATCHES_ANYTHING, and querying for "col = 5", then match either * null or 5. Two intervals are required [null,null] and [5,5] *
  • if NULL_MATCHES_NULL, and querying "col = null" then null may be matched * with the point interval [null,null] *
  • otherwise, null cannot be matched, so a query like "col < 1" becomes * (null,1) *
* * @author John Pham * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoColumnHistogram.java#10 $ */ public class FarragoColumnHistogram implements RelStatColumnStatistics { //~ Instance fields -------------------------------------------------------- private FemAbstractColumn column; private SargIntervalSequence sequence; private Timestamp labelTimestamp; private FemColumnHistogram histogram; private int barCount; private List bars; Double selectivity; Double cardinality; //~ Constructors ----------------------------------------------------------- /** * Initializes a column statistics reader. The statistics are not actually * analyzed until the user calls {@link #evaluate()}. * * @param column column to analyze * @param sequence optional predicate on the column * * @deprecated */ protected FarragoColumnHistogram( FemAbstractColumn column, SargIntervalSequence sequence) { this(column, sequence, null); } /** * Initializes a column statistics reader. The statistics are not actually * analyzed until the user calls {@link #evaluate()}. * * @param column column to analyze * @param sequence optional predicate on the column * @param labelTimestamp the creation timestamp of the label setting that * determines which set of stats should be used; null if there is no label * setting */ protected FarragoColumnHistogram( FemAbstractColumn column, SargIntervalSequence sequence, Timestamp labelTimestamp) { this.column = column; this.sequence = sequence; this.labelTimestamp = labelTimestamp; } //~ Methods ---------------------------------------------------------------- // implement RelStatColumnStatistics public Double getSelectivity() { return selectivity; } // implement RelStatColumnStatistics public Double getCardinality() { return cardinality; } /** * Analyzes column histogram to determine the selectivity and cardinality of * the specified search condition. */ protected void evaluate() { histogram = FarragoCatalogUtil.getHistogram(column, labelTimestamp); if (histogram == null) { return; } Long valueCount = histogram.getDistinctValueCount(); if (valueCount == null) { selectivity = (sequence == null) ? 1.0 : null; cardinality = null; return; } if (sequence == null) { selectivity = 1.0; cardinality = Double.valueOf(valueCount); return; } barCount = histogram.getBarCount(); bars = histogram.getBar(); assert (bars.size() == barCount) : "invalid histogram bar count"; List coverages = getCoverage(sequence); if (coverages == null) { selectivity = null; cardinality = null; return; } readCoverages(coverages); } /** * Computes the histogram bar coverage of an ordered sequence of intervals. * Coverage can only be computed if the end points of each interval in the * sequence are either literal or infinite. * * @param sequence sequence to lookup * * @return List of HistogramBarCoverage instance of null if coverage cannot * be computed. */ private List getCoverage( SargIntervalSequence sequence) { List coverages = new ArrayList(barCount); for (int i = 0; i < barCount; i++) { coverages.add(new HistogramBarCoverage()); } int minBar = 0; for (SargInterval interval : sequence.getList()) { if (!checkEndpoint(interval.getLowerBound()) || !checkEndpoint(interval.getUpperBound())) { // Can't handle non-literal endpoints, signal the caller. return null; } HistogramRange range = new HistogramRange(bars, interval, minBar); range.evaluate(); if (range.isEmpty()) { continue; } String minVal = bars.get(range.firstBar).getStartingValue(); HistogramBarCoverage.addRange(coverages, range, minVal); minBar = range.getLastBar(); } return coverages; } /** * Check if the given SargEndpoint is infinite or is bounded by a literal * expression. * * @param endpoint the endpoint to evaluate * * @return true if the endpoint is infinite or bounded by a literal; false * otherwise */ private boolean checkEndpoint(SargEndpoint endpoint) { return !endpoint.isFinite() || (endpoint.getCoordinate() instanceof RexLiteral); } /** * Reads collective coverages finally make estimates on requested * attributes. This implementation looks at each bar separately, estimating * how much of each bar is covered. It then accounts for that bar's * contribution to the entire results. * * @param coverages list of coverage for each bar */ private void readCoverages(List coverages) { // determine a correction factor: // actual values = sampled values * correction // For computed statistics, the correction will be 1.0. For estimated // statistics it will be >= 1.0. Long histValues = histogram.getDistinctValueCount(); Long sampleValues = 0L; for (FemColumnHistogramBar bar : bars) { sampleValues += bar.getValueCount(); } assert (histValues >= sampleValues); Double correction = NumberUtil.divide( Double.valueOf(histValues), Double.valueOf(sampleValues)); Double totalFraction = 0.0; Double totalValues = 0.0; for (int i = 0; i < coverages.size(); i++) { // estimate the actual cardinality of the bar Double barValues = NumberUtil.multiply( Double.valueOf(bars.get(i).getValueCount()), correction); HistogramBarCoverage coverage = coverages.get(i); Double fraction = coverage.estimateFraction(barValues); // the last bar may contain a few less rows than the others if (i == (coverages.size() - 1)) { fraction = NumberUtil.multiply( fraction, ((double) histogram.getRowsLastBar()) / histogram.getRowsPerBar()); } Double values = coverage.estimateCardinality(barValues); totalFraction = NumberUtil.add(totalFraction, fraction); totalValues = NumberUtil.add(totalValues, values); } totalFraction = NumberUtil.divide(totalFraction, (double) bars.size()); selectivity = totalFraction; cardinality = totalValues; } /** * Compares a value in a histogram with a Sarg coordinate * * @param histValue a histogram value * @param coordinate a sarg coordinate, or a null pointer to represent the * null value. An infinite coordinate is not recognized by this function. * * @return -1 if value is less than point, 0 if value equals point, or 1 if * value is greater than point */ protected static int compare(String histValue, RexLiteral coordinate) { // treat null values as the least value Comparable sargValue = (coordinate == null) ? null : coordinate.getValue(); if ((histValue == null) && (sargValue == null)) { return 0; } else if (histValue == null) { return -1; } else if (sargValue == null) { return 1; } RexLiteral rexValue = RexLiteral.fromJdbcString( coordinate.getType(), coordinate.getTypeName(), histValue); int comparison = rexValue.getValue().compareTo(sargValue); return comparison; } //~ Inner Classes ---------------------------------------------------------- /** * Histogram range represents a set of bars in a histogram */ private class HistogramRange { private List bars; private SargInterval interval; private int minBar; private boolean empty; private int firstBar; private int lastBar; /** * Initializes a range of histogram bars spanning a search interval * * @param bars histogram bars to search * @param interval the search interval * @param minBar the first bar to search */ protected HistogramRange( List bars, SargInterval interval, int minBar) { this.bars = bars; this.interval = interval; this.minBar = minBar; } /** * Searches through the histogram to find the first and last bars the * interval may cover in the histogram. This range may be empty. */ protected void evaluate() { int start = findStartBar( minBar, interval.getLowerBound()); int end = findEndBar( start, interval.getUpperBound()); if (start == end) { empty = true; firstBar = lastBar = -1; } else { empty = false; firstBar = start; lastBar = end - 1; } } /** * Returns whether the range is empty */ protected boolean isEmpty() { return empty; } /** * Returns the zero based index of the first bar in the range, or -1 if * the range is empty. */ protected int getFirstBar() { return firstBar; } /** * Returns the zero based index of the last bar in the range, or -1 if * the range is empty. */ protected int getLastBar() { return lastBar; } /** * Finds the first histogram bar which may contain the specified * starting search point, or points greater than the search point. We * can rule out histogram bars which end before the search point. * However, we can never rule out the last histogram bar, because it has * no definite end. * * @param min index of first histogram bar to search * @param point start point to search for * * @return index of first bar not containing point */ private int findStartBar(int min, SargEndpoint point) { // if the start is "-infinity" then the range starts at the // first bar if (!point.isFinite()) { return 0; } RexLiteral coordinate = point.isNull() ? null : (RexLiteral) point.getCoordinate(); boolean open = (point.getStrictness() == SargStrictness.OPEN); int start; for (start = min; (start + 1) < bars.size(); start++) { // The end of the current bar can be anything up to the start // of the next bar, inclusive. Here we skip past bars that are // less than the search value. FemColumnHistogramBar nextBar = bars.get(start + 1); int comparison = compare( nextBar.getStartingValue(), coordinate); if ((comparison < 0) || (open && (comparison == 0))) { continue; } break; } return start; } /** * Finds the first histogram bar which does not contain the specified * point. A bar which does not contain the end point will have a * starting value greater than the point. * *

If all bars may contain the search point, returns the index of the * last bar + 1. * * @param min index of first histogram bar to search * @param point point to search for * * @return index of first bar not containing point */ private int findEndBar(int min, SargEndpoint point) { // return end for "+infinity" if (!point.isFinite()) { return bars.size(); } RexLiteral coordinate = point.isNull() ? null : (RexLiteral) point.getCoordinate(); boolean open = (point.getStrictness() == SargStrictness.OPEN); int end; for (end = min; end < bars.size(); end++) { // if the histogram bar starts starts after the point // we know the bar does not contain the point FemColumnHistogramBar bar = bars.get(end); int comparison = compare( bar.getStartingValue(), coordinate); if ((comparison > 0) || (open && (comparison == 0))) { break; } } return end; } } /** * Describes which points and ranges lie on a histogram bar */ private static class HistogramBarCoverage { private boolean entireBar; private int cardinalityPoint; private int cardinalityRanges; private int selectivityPoints; private int selectivityRanges; /** * Determines how a histogram range, possibly spanning several bars, * covers each histogram bar, and accumulates a running total of the * coverage. * * @param coverages set of coverages for each bar * @param range histogram bar range to be tabulated */ protected static void addRange( List coverages, HistogramRange range, String minVal) { // continue if range does not overlap any bars if (range.isEmpty()) { return; } // cardinality fields if (range.interval.isPoint()) { coverages.get(range.firstBar).cardinalityPoint++; } else { for (int i = range.firstBar; i <= range.lastBar; i++) { coverages.get(i).cardinalityRanges++; } } // selectivity fields (handled separately since we are // in the case where points span multiple bars) if (range.firstBar == range.lastBar) { if (range.interval.isPoint()) { coverages.get(range.firstBar).selectivityPoints++; } else { coverages.get(range.firstBar).selectivityRanges++; } // return since single bar ranges rarely cover an entire bar return; } for (int i = range.firstBar; i <= range.lastBar; i++) { coverages.get(i).selectivityRanges++; } // look for entire bars. the first bar of the range is fully // covered if the lower bound is infinite or less than the // first bar of the histogram range (note that the range // has at least two bars) assert (range.firstBar != range.lastBar); SargEndpoint lower = range.interval.getLowerBound(); if (!lower.isFinite()) { assert (range.firstBar == 0) : "-infinity does not span first histogram bar"; coverages.get(0).entireBar = true; } else { RexLiteral coordinate = (RexLiteral) lower.getCoordinate(); int comparison = compare(minVal, coordinate); if ((comparison == 1) || ((comparison == 0) && lower.isClosed())) { coverages.get(0).entireBar = true; } } // all intermediate bars are fully covered for (int i = range.firstBar + 1; i < range.lastBar; i++) { coverages.get(i).entireBar = true; } // the last bar may be covered if there is no upper bound if (!range.interval.getUpperBound().isFinite()) { assert (range.lastBar == (coverages.size() - 1)) : "+infinity does not span last histogram bar"; coverages.get(range.lastBar).entireBar = true; } } /** * Estimates what percentage of a bar is covered, based on the bar's * total cardinality. * * @param cardinality the expected cardinality of the bar * * @return an estimate from 0.0 to 1.0 representing a fraction of a bar, * or null if no reliable estimate can be made */ protected Double estimateFraction( Double cardinality) { if (entireBar) { return Double.valueOf(1); } // if only points are provided, cardinality is required to // make an educated guess with them if ((cardinality == null) && (selectivityRanges == 0)) { return null; } // start with the contribution by points contained by bar double fraction = 0; if ((cardinality != null) && (selectivityPoints > 0)) { // assume cardinality is at least 1 for the division cardinality = Math.max(cardinality, 1.0); fraction = Math.min(selectivityPoints / cardinality, 1.0); } // add in a half for any remaining points double remaining = 1 - fraction; if (selectivityRanges > 0) { fraction += remaining / 2; } return fraction; } /** * Estimates the cardinality of the column after applying a predicate. * * @param cardinality the expected cardinality of the bar * * @return an estimate of the cardinality of the column after applying * the predicate, or null if no reliable estimate can be made */ protected Double estimateCardinality(Double cardinality) { double estimatedBarCardinality = (cardinality != null) ? cardinality : 0; assert (estimatedBarCardinality >= 0) : "histogram bar contained negative number of distinct values"; // Start with the points as a basis for cardinality. // Return this if it represents the entire bar, or if // there are no ranges. double points = cardinalityPoint; if (((points > 0) && (points >= estimatedBarCardinality)) || (cardinalityRanges == 0)) { return points; } // Otherwise, there is some kind of range and we need the bar's // estimated cardinality to resolve our filtered cardinality if (cardinality == null) { return null; } // A range spanning the entire bar gets half the cardinality, // while other ranges get half of the remaining points if (entireBar) { points = Math.max(estimatedBarCardinality, points); } // in case we have an empty bar double remainingPoints = Math.max(estimatedBarCardinality - points, 0.0); return Double.valueOf(points + (remainingPoints / 2)); } } } // End FarragoColumnHistogram.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/codegen/0000755000175000017500000000000011173714170023403 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/codegen/package.html0000444000175000017500000000113011173714170025655 0ustar drazzibdrazzib Package net.sf.farrago.catalog.codegen Provides build-time utilities for generating code from the repository model.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/package.html#7 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/codegen/FactoryGen.java0000444000175000017500000003102611173714170026307 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/FactoryGen.java#21 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog.codegen; import java.io.*; import java.lang.reflect.*; import java.util.*; import javax.jmi.model.*; import javax.jmi.reflect.*; import net.sf.farrago.*; import net.sf.farrago.catalog.*; import org.eigenbase.jmi.*; import org.eigenbase.util.*; import org.netbeans.lib.jmi.util.*; /** * FactoryGen generates a factory class for a JMI model. It's purely a * convenience; JMI already provides factory methods, but their invocation * requires a long ugly expression involving lots of redundancy. For an example * of the generated output, see FarragoMetadataFactory. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/FactoryGen.java#21 $ */ public class FactoryGen { //~ Static fields/initializers --------------------------------------------- private static final int MAX_LARGE_NUMERICS = 4; //~ Methods ---------------------------------------------------------------- /** * Main generator entry point invoked by build.xml (target * "generateMetadataFactory"). * * @param args

    *
  • args[0] = target .java file for interface output *
  • args[1] = target .java file for class output *
  • args[2] = target package name *
  • args[3] = target interface name *
  • args[4] = target class name *
  • args[5] = source package Java metaclass name *
  • args[6] = source extent name *
  • (optional) args[7] = model timestamp *
*/ public static void main(String [] args) throws ClassNotFoundException, IOException { assert ((args.length == 7) || (args.length == 8)); FileWriter writerInterface = new FileWriter(args[0]); FileWriter writerClass = new FileWriter(args[1]); String targetPackageName = args[2]; String targetInterfaceName = args[3]; String targetClassName = args[4]; String sourcePackageJavaMetaclassName = args[5]; String sourceExtentName = args[6]; String modelTimestamp = "NO_TIMESTAMP_ASSIGNED"; if (args.length == 8) { modelTimestamp = args[7]; } FarragoModelLoader modelLoader = null; PrintWriter pwInterface = new PrintWriter(writerInterface); PrintWriter pwClass = new PrintWriter(writerClass); PrintWriter pw = new ForkWriter(pwInterface, pwClass); try { pw.println("// This code generated by FactoryGen -- do not edit"); pw.println(); pw.print("package "); pw.print(targetPackageName); pw.println(";"); pw.println(); pwClass.println( "public class " + targetClassName + " implements " + targetInterfaceName); pwInterface.println("public interface " + targetInterfaceName); pw.println("{"); pwClass.print(" private "); pwClass.print(sourcePackageJavaMetaclassName); pwClass.println(" rootPackage;"); pwClass.println(); pw.print(" public void setRootPackage("); pw.print(sourcePackageJavaMetaclassName); pw.println(" p)"); pw.println(" {"); pw.println(" this.rootPackage = p;"); pw.println(" }"); pw.println(); pw.print(" public "); pw.print(sourcePackageJavaMetaclassName); pw.println(" getRootPackage()"); pw.println(" {"); pw.println(" return rootPackage;"); pw.println(" }"); pw.println(); pw.print(" public String"); pw.println(" getCompiledModelTimestamp()"); pw.println(" {"); pw.println(" return \"" + modelTimestamp + "\";"); pw.println(" }"); pw.println(); modelLoader = new FarragoModelLoader(); FarragoPackage farragoPackage = modelLoader.loadModel(sourceExtentName, false); Class sourcePackageInterface = Class.forName( sourcePackageJavaMetaclassName); RefPackage rootPackage = findPackage( farragoPackage, sourcePackageInterface); generatePackage(pw, rootPackage, "rootPackage"); pw.println("}"); } finally { pw.flush(); writerInterface.close(); writerClass.close(); if (modelLoader != null) { modelLoader.close(); } } } private static RefPackage findPackage(RefPackage refPackage, Class iface) { if (iface.isInstance(refPackage)) { return refPackage; } Collection allPackages = refPackage.refAllPackages(); for (RefPackage p : allPackages) { RefPackage f = findPackage(p, iface); if (f != null) { return f; } } return null; } private static void generatePackage( PrintWriter pw, RefPackage refPackage, String packageAccessor) throws ClassNotFoundException { TagProvider tagProvider = new TagProvider(); // first generate accessor for package Class pkgInterface = JmiObjUtil.getJavaInterfaceForRefPackage(refPackage); pw.print(" public "); pw.print(pkgInterface.getName()); pw.print(" get"); pw.print(ReflectUtil.getUnqualifiedClassName(pkgInterface)); pw.println("()"); pw.println(" {"); pw.print(" return "); pw.print(packageAccessor); pw.println(";"); pw.println(" }"); pw.println(); // then generate factory methods for all classes in package Collection allClasses = refPackage.refAllClasses(); for (RefClass refClass : allClasses) { MofClass mofClass = (MofClass) refClass.refMetaObject(); if (mofClass.isAbstract()) { continue; } Class classInterface = JmiObjUtil.getJavaInterfaceForRefObject(refClass); validateClass(classInterface); String unqualifiedInterfaceName = ReflectUtil.getUnqualifiedClassName(classInterface); pw.print(" public "); pw.print(classInterface.getName()); pw.print(" new"); pw.print(unqualifiedInterfaceName); pw.println("()"); pw.println(" {"); pw.print(" return get"); pw.print(ReflectUtil.getUnqualifiedClassName(pkgInterface)); pw.print("().get"); pw.print(unqualifiedInterfaceName); pw.print("().create"); pw.print(unqualifiedInterfaceName); pw.println("();"); pw.println(" }"); pw.println(); } Collection allPackages = refPackage.refAllPackages(); for (RefPackage refSubPackage : allPackages) { MofPackage mofSubPackage = (MofPackage) refSubPackage.refMetaObject(); String subPackageName = mofSubPackage.getName(); // This is a trick to detect and skip the package aliases which are // created for imports. Package javaPackage = refPackage.getClass().getPackage(); Package childJavaPackage = refSubPackage.getClass().getPackage(); if (!childJavaPackage.getName().equals( javaPackage.getName() + "." + subPackageName.toLowerCase())) { continue; } subPackageName = tagProvider.getSubstName(mofSubPackage); generatePackage( pw, refSubPackage, packageAccessor + ".get" + subPackageName + "()"); } } /** * Validates the given class. In particular, this method detects classes * that can trigger intermittent bugs in Farrago's MDR implementation. * * @param classInterface class to validate * * @see #countLargeNumerics(Class) */ private static void validateClass(Class classInterface) { int numLargeNumerics = countLargeNumerics(classInterface); if (numLargeNumerics > MAX_LARGE_NUMERICS) { throw new RuntimeException( classInterface.getName() + ": A maximum of 4 long and/or double attributes are allowed " + "in any catalog class. See FRG-295."); } } /** * Counts the number of attributes in the given class that are of type * long or double. The count includes attributes from super * interfaces. This method looks at only the methods whose names begin with * "set" and are therefore mutators/setters. Attributes of type {@link * java.lang.Long} or {@link java.lang.Double} are not counted as large * numberics (because they do not require extra operand stack space). * *

This method can be removed when the corresponding bug in MDR is fixed. * * @param classInterface a Farrago catalog interface class * * @return the number of longs and doubles in the class * * @see FRG-295 */ private static int countLargeNumerics(Class classInterface) { if ((classInterface == null) || !classInterface.getName().startsWith("net.sf.farrago.fem")) { return 0; } int numLargeNumerics = 0; for (Class superInterface : classInterface.getInterfaces()) { numLargeNumerics += countLargeNumerics(superInterface); } for (Method method : classInterface.getDeclaredMethods()) { if (method.getName().startsWith("set")) { Class [] paramTypes = method.getParameterTypes(); if (((paramTypes.length == 1) && (paramTypes[0] == long.class)) || (paramTypes[0] == double.class)) { numLargeNumerics++; } } } return numLargeNumerics; } //~ Inner Classes ---------------------------------------------------------- /** * Writer which takes two underlying writers, and automatically writes * method bodies to one, and method prototypes to the other. */ private static class ForkWriter extends PrintWriter { private boolean inMethod; private final PrintWriter pwInterface; private final PrintWriter pwClass; protected ForkWriter(PrintWriter pwInterface, PrintWriter pwClass) { super(pwClass); this.pwInterface = pwInterface; this.pwClass = pwClass; } public void print(String x) { pwClass.print(x); if (!inMethod) { pwInterface.print(x); } } public void println(String x) { pwClass.println(x); if (x.equals(" {")) { inMethod = true; } if (!inMethod) { pwInterface.println(x); } if (x.equals(" }")) { inMethod = false; pwInterface.println(";"); } } public void flush() { pwInterface.flush(); pwClass.flush(); } } } // End FactoryGen.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/codegen/ProxyGen.java0000444000175000017500000007754111173714170026035 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/ProxyGen.java#23 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog.codegen; import java.io.*; import java.lang.reflect.*; import java.util.*; import javax.jmi.model.*; import javax.jmi.reflect.*; import net.sf.farrago.*; import net.sf.farrago.catalog.*; import org.eigenbase.jmi.*; import org.eigenbase.util.*; /** * ProxyGen generates read-only C++ JNI proxies for MDR-generated Java * interfaces (something like a stripped-down JACE). It uses an unholy mix of * Java/JMI navel-scrutiny. For an example of its output, see * FemGeneratedClasses.h and FemGeneratedMethods.h in //open/fennel/farrago. * *

To understand this generator, it's important to distinguish among * MOF/UML/JMI classes (which are metadata objects), repository-generated Java * interfaces, and the C++ proxy classes generated here.

* * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/ProxyGen.java#23 $ */ public class ProxyGen { //~ Static fields/initializers --------------------------------------------- private static final Comparator classNameComparator = new Comparator() { public int compare( Class o1, Class o2) { final String name1 = o1.getName(); final String name2 = o2.getName(); return name1.compareTo(name2); } }; private static final Comparator methodNameComparator = new Comparator() { public int compare(Method m1, Method m2) { String name1 = mangle(m1.getName()); String name2 = mangle(m2.getName()); return name1.compareTo(name2); } private String mangle(String name) { if ((name.length() > 3) && (name.startsWith("get") || name.startsWith("set"))) { return name.substring(3) + "_" + name.substring(0, 3); } else if ((name.length() > 2) && name.startsWith("is")) { return name.substring(2) + "_" + name.substring(0, 2); } else { return name; } } }; //~ Instance fields -------------------------------------------------------- /** * Map from Class to corresponding C++ type name as String. */ private Map cppTypeMap = new HashMap(); /** * Map from Class to RefClass for everything in genInterfaces. */ private Map javaToJmiMap = new HashMap(); /** * Map from Class to corresponding Java type String to use in method * signatures. */ private Map javaTypeMap = new HashMap(); /** * PrintWriter used to generate output. */ private PrintWriter pw; /** * Set containing all interfaces (represented as Class objects) for which * C++ proxies are to be generated. */ private Set genInterfaces = new HashSet(); /** * Set containing all base interfaces (represented as Class objects) from * which C++ proxies are to inherit. */ private Set baseInterfaces = new HashSet(); /** * Set containing interfaces (represented as Class objects) whose proxy * definition has not yet been generated. This is used to induce topological * order for the inheritance graph. */ private Set undefinedInterfaces = new HashSet(); /** * Set containing all interfaces (represented as Class objects) for which * C++ enums are to be generated. */ private Set genEnums = new HashSet(); private String genPrefix; private String basePrefix; private String visitorClassName; private String visitorBaseName; //~ Constructors ----------------------------------------------------------- /** * Initialize a new ProxyGen. */ public ProxyGen( String genPrefix, String basePrefix) { this.genPrefix = genPrefix; this.basePrefix = basePrefix; visitorClassName = genPrefix + "Visitor"; if (basePrefix == null) { visitorBaseName = "JniProxyVisitor"; } else { visitorBaseName = basePrefix + "Visitor"; } cppTypeMap.put(Integer.TYPE, new CppTypeInfo("int32_t")); cppTypeMap.put( Integer.class, new CppTypeInfo("int32_t", "constructJavaInteger", "int32Value")); javaTypeMap.put(Integer.TYPE, "I"); cppTypeMap.put(Long.TYPE, new CppTypeInfo("int64_t")); cppTypeMap.put( Long.class, new CppTypeInfo("int64_t", "constructJavaLong", "int64Value")); javaTypeMap.put(Long.TYPE, "J"); cppTypeMap.put(Short.TYPE, new CppTypeInfo("int16_t")); cppTypeMap.put( Short.class, new CppTypeInfo("int16_t", "constructJavaShort", "int16Value")); javaTypeMap.put(Short.TYPE, "S"); cppTypeMap.put(Double.TYPE, new CppTypeInfo("double")); cppTypeMap.put( Double.class, new CppTypeInfo("double", "constructJavaDouble", "doubleValue")); javaTypeMap.put(Double.TYPE, "D"); cppTypeMap.put(Float.TYPE, new CppTypeInfo("float")); cppTypeMap.put( Float.class, new CppTypeInfo("float", "constructJavaFloat", "floatValue")); javaTypeMap.put(Float.TYPE, "F"); cppTypeMap.put(Boolean.TYPE, new CppTypeInfo("bool")); cppTypeMap.put( Boolean.class, new CppTypeInfo("bool", "constructJavaBoolean", "boolValue")); javaTypeMap.put(Boolean.TYPE, "Z"); cppTypeMap.put( String.class, new CppTypeInfo( "std::string", "constructJavaString", "constructString")); } //~ Methods ---------------------------------------------------------------- /** * Adds all classes from a JMI package to the set of interfaces to be * generated. * * @param refPackage the source JMI package */ public void addGenClasses(RefPackage refPackage) throws ClassNotFoundException { Collection allRefClasses = refPackage.refAllClasses(); for (RefClass refClass : allRefClasses) { Class clazz = JmiObjUtil.getJavaInterfaceForRefObject(refClass); genInterfaces.add(clazz); javaToJmiMap.put(clazz, refClass); } } /** * Adds all classes from a JMI package to the set of interfaces to use as * bases. * * @param refPackage the source JMI package */ public void addBaseClasses(RefPackage refPackage) throws ClassNotFoundException { Collection allRefClasses = refPackage.refAllClasses(); for (RefClass refClass : allRefClasses) { Class clazz = JmiObjUtil.getJavaInterfaceForRefObject(refClass); baseInterfaces.add(clazz); javaToJmiMap.put(clazz, refClass); } } /** * Generates the C++ class definition for one interface. * * @param clazz the interface */ public void generateClassDefinition(Class clazz) { assert (clazz.isInterface()); if (!undefinedInterfaces.contains(clazz)) { // this class already done return; } Class [] bases = clazz.getInterfaces(); // make sure bases are already defined for (int i = 0; i < bases.length; ++i) { if (bases[i] == RefObject.class) { continue; } generateClassDefinition(bases[i]); } undefinedInterfaces.remove(clazz); // TODO jvs 6-Apr-2009: instead of hard-coding FENNEL_FARRAGO_EXPORT, // make it a generator parameter so that extension projects // can supply their own DLL export macros pw.println("class FENNEL_FARRAGO_EXPORT " + getCppClassName(clazz)); pw.print(": virtual public JniProxy"); for (int i = 0; i < bases.length; ++i) { if (bases[i] == RefObject.class) { continue; } pw.print(", virtual public "); pw.print(getCppClassName(bases[i])); } pw.println(); pw.println("{"); pw.println("public:"); Method [] methods = clazz.getDeclaredMethods(); methods = toSortedArray(methods); for (int i = 0; i < methods.length; ++i) { if (isGetter(methods[i])) { generateMethodDeclaration(methods[i]); } else if (isSetter(methods[i])) { generateSetterMethodDeclaration(methods[i]); } } pw.println("};"); pw.println(); } /** * Generates the C++ code for all class definitions. * * @param pw output */ public void generateClassDefinitions(PrintWriter pw) { this.pw = pw; pw.println("// This code generated by ProxyGen -- do not edit"); pw.println(); // First, generate forward references for all classes we're going to // generate. This makes possible any kind of class dependency graph, // since objects are always returned by reference. Class [] interfaces = toSortedArray(genInterfaces); for (int i = 0; i < interfaces.length; i++) { Class clazz = interfaces[i]; generateClassDeclaration(clazz); pw.println(); } // Next, generate the actual class definitions. We need to generate // base classes before derived classes, so use undefinedInterfaces to // keep track. undefinedInterfaces.clear(); undefinedInterfaces.addAll(genInterfaces); for (int i = 0; i < interfaces.length; i++) { Class clazz = interfaces[i]; generateClassDefinition(clazz); } // Finally, generate the visitor interface with a visitor method // overload for each class. pw.println( "class FENNEL_FARRAGO_EXPORT " + visitorClassName + " : virtual public " + visitorBaseName); pw.println("{"); pw.println("public:"); pw.println( "static JniProxyVisitTable<" + visitorClassName + "> visitTbl;"); for (int i = 0; i < interfaces.length; i++) { Class clazz = interfaces[i]; generateVisitDeclaration(clazz); } pw.println("};"); pw.println(); } /** * Generates the C++ code for all enumerations. * * @param pw output */ public void generateEnumDefinitions(PrintWriter pw) throws Exception { pw.println("// This code generated by ProxyGen -- do not edit"); pw.println(); CppEnumGen enumGen = new CppEnumGen(pw); final Class [] enumInterfaces = toSortedArray(genEnums); for (int i = 0; i < enumInterfaces.length; i++) { Class enumInterface = enumInterfaces[i]; Class enumClass = Class.forName(enumInterface.getName() + "Enum"); enumGen.generateEnumForClass( ReflectUtil.getUnqualifiedClassName(enumInterface), enumClass, enumClass); } } /** * Generates the C++ code for all method definitions. * * @param pw output */ public void generateClassImplementations(PrintWriter pw) { this.pw = pw; pw.println("// This code generated by ProxyGen -- do not edit"); pw.println(); // First, generate static definitions such as all method ID's used by // generated getters. pw.println( "JniProxyVisitTable<" + visitorClassName + "> " + visitorClassName + "::visitTbl;"); pw.println(); Class [] interfaces = toSortedArray(genInterfaces); for (int i = 0; i < interfaces.length; i++) { Class clazz = interfaces[i]; generateStaticDefinitions(clazz); } // Next, generate the static method which performs the JNI lookup for // methods. pw.println( "void staticInit" + genPrefix + "(JniEnvRef pEnv,JniProxyVisitTableBase &visitTbl)"); pw.println("{"); pw.println("jclass jClass;"); for (int i = 0; i < interfaces.length; i++) { Class clazz = interfaces[i]; generateStaticInitialization(clazz); } pw.println("}"); pw.println(); // Finally, generate the getter implementations for each method. for (int i = 0; i < interfaces.length; i++) { Class clazz = interfaces[i]; Method [] methods = clazz.getDeclaredMethods(); methods = toSortedArray(methods); for (int j = 0; j < methods.length; ++j) { if (isGetter(methods[j])) { generateMethodDefinition(methods[j]); pw.println(); } else if (isSetter(methods[j])) { generateSetterMethodDefinition(methods[j]); pw.println(); } } } } /** * Converts collection into an array of classes sorted by name. This is * necessary in order to make the output deterministic. */ private static Class [] toSortedArray(Collection collection) { Class [] classes = collection.toArray(new Class[collection.size()]); Arrays.sort(classes, classNameComparator); return classes; } /** * Sorts an array of Methods. This is necessary in order to make output * deterministic. Necessary because, for instance, {@link * Class#getDeclaredMethods()} does not guarantee that it returns methods in * any particular order, and in practice the order changes across versions * (vendors?) of javac. */ private static Method [] toSortedArray(Method [] methods) { Arrays.sort(methods, methodNameComparator); return methods; } /** * Generates the C++ declaration for one (getter) method. * * @param method . */ public void generateMethodDeclaration(Method method) { String cppTypeName = getCppReturnTypeName(method); pw.print(cppTypeName); pw.print(" "); pw.print(method.getName()); pw.println("();"); // TODO: make private? pw.print("static jmethodID meth_"); pw.print(method.getName()); pw.println(";"); } /** * Generates the C++ declaration for one setter method and its corresponding * clear method (if any). Only setters that take non-primitive types get * clear methods. * * @param method . */ public void generateSetterMethodDeclaration(Method method) { CppTypeInfo cppTypeInfo = getCppParameterTypeInfo(method.getParameterTypes()[0]); String cppTypeName = cppTypeInfo.cppTypeName; pw.print("void "); pw.print(method.getName()); pw.print("(const "); pw.print(cppTypeName); pw.println(" &valueRef);"); if (!cppTypeInfo.isPrimitive) { pw.print("void clear"); pw.print(method.getName().substring(3)); pw.println("();"); } // TODO: make private? pw.print("static jmethodID meth_"); pw.print(method.getName()); pw.println(";"); } /** * Generates the C++ definition for one (getter) method. * * @param method . */ public void generateMethodDefinition(Method method) { String cppTypeName = getCppReturnTypeName(method); pw.print(cppTypeName); pw.print(" "); pw.print(getCppClassName(method.getDeclaringClass())); pw.print("::"); pw.print(method.getName()); pw.println("()"); pw.println("{"); Class returnType = method.getReturnType(); CppTypeInfo cppTypeInfo = cppTypeMap.get(returnType); if (cppTypeInfo != null) { if (cppTypeInfo.isPrimitive) { pw.print("return pEnv->Call"); pw.print(Character.toUpperCase(returnType.getName().charAt(0))); pw.print(returnType.getName().substring(1)); pw.print("Method(jObject,meth_"); pw.print(method.getName()); pw.println(");"); } else { // convert a jobject into a C++ type (std::string or // a numeric such as int64_t) pw.print("return "); pw.print(cppTypeInfo.unboxingHelperMethod); pw.print("("); pw.print("pEnv->CallObjectMethod(jObject,meth_"); pw.print(method.getName()); pw.println("));"); } } else if (RefEnum.class.isAssignableFrom(returnType)) { // TODO jvs 29-April-2004: Need to find a way to filter out // enumerations from base packages, otherwise we'll generate // duplicates. genEnums.add(returnType); pw.print("std::string symbol = constructString("); pw.print("JniUtil::toString(pEnv,"); pw.print("pEnv->CallObjectMethod(jObject,meth_"); pw.print(method.getName()); pw.println(")));"); String enumName = ReflectUtil.getUnqualifiedClassName(returnType); pw.print("return static_cast<"); pw.print(enumName); pw.print(">(JniUtil::lookUpEnum("); pw.print(enumName); pw.println("_names,symbol));"); } else { pw.print(cppTypeName); pw.println(" p;"); pw.println("p->pEnv = pEnv;"); pw.print("p->jObject = pEnv->CallObjectMethod(jObject,meth_"); pw.print(method.getName()); pw.println(");"); if (Collection.class.isAssignableFrom(returnType)) { pw.println("p.jIter = JniUtil::getIter(p->pEnv,p->jObject);"); pw.println("++p;"); } else { pw.println("if (!p->jObject) p.reset();"); } pw.println("return p;"); } pw.println("}"); } /** * Generates the C++ definition for one setter method and its corresponding * clear method (if any). * * @param method . */ public void generateSetterMethodDefinition(Method method) { Class paramType = method.getParameterTypes()[0]; CppTypeInfo cppTypeInfo = getCppParameterTypeInfo(paramType); pw.print("void "); pw.print(getCppClassName(method.getDeclaringClass())); pw.print("::"); pw.print(method.getName()); pw.print("(const "); pw.print(cppTypeInfo.cppTypeName); pw.println(" &valueRef)"); pw.println("{"); // convert C++ type into a jobject pw.print("pEnv->CallVoidMethod(jObject,meth_"); pw.print(method.getName()); pw.print(","); pw.print(cppTypeInfo.boxingHelperMethod); pw.println("(valueRef));"); pw.println("}"); if (!cppTypeInfo.isPrimitive) { pw.print("void "); pw.print(getCppClassName(method.getDeclaringClass())); pw.print("::clear"); pw.print(method.getName().substring(3)); pw.println("()"); pw.println("{"); pw.print("pEnv->CallVoidMethod(jObject,meth_"); pw.print(method.getName()); pw.println(",NULL);"); pw.println("}"); } } /** * Main generator entry point invoked by build.xml (target * "generateFemCpp"). The catalog must already exist before running the * generator. * * @param args * *
    *
  • args[0] = filename for C++ class definition output *
  • args[1] = filename for C++ class implementation output *
  • args[2] = filename for C++ enumeration output *
  • args[3] = qualified name of source model package *
  • args[4] = prefix to use for generated objects *
  • args[5] = (optional) qualified name of model package to reference as * base; if this is not specified, generated objects are base classes *
  • args[6] = (optional) prefix to reference for base classes; must be * specified together with previous argument *
*/ public static void main(String [] args) throws Exception { assert (args.length > 3); FileWriter defWriter = new FileWriter(args[0]); FileWriter implWriter = new FileWriter(args[1]); FileWriter enumWriter = new FileWriter(args[2]); String sourcePackageName = args[3]; String genPrefix = args[4]; String basePackageName = null; String basePrefix = null; if (args.length > 5) { assert (args.length == 7); basePackageName = args[5]; basePrefix = args[6]; } FarragoModelLoader modelLoader = null; ProxyGen proxyGen = new ProxyGen(genPrefix, basePrefix); try { modelLoader = new FarragoModelLoader(); FarragoPackage farragoPackage = modelLoader.loadModel("FarragoCatalog", false); proxyGen.addGenClasses( findPackage(farragoPackage, sourcePackageName)); if (basePackageName != null) { proxyGen.addBaseClasses( findPackage(farragoPackage, basePackageName)); } PrintWriter pw = new PrintWriter(defWriter); proxyGen.generateClassDefinitions(pw); pw.flush(); pw = new PrintWriter(implWriter); proxyGen.generateClassImplementations(pw); pw.flush(); pw = new PrintWriter(enumWriter); proxyGen.generateEnumDefinitions(pw); pw.flush(); } finally { defWriter.close(); implWriter.close(); enumWriter.close(); if (modelLoader != null) { modelLoader.close(); } } } private static RefPackage findPackage( RefPackage rootPackage, String qualifiedName) { String [] sourcePackageNames = qualifiedName.split("\\."); RefPackage sourcePackage = JmiObjUtil.getSubPackage( rootPackage, sourcePackageNames, sourcePackageNames.length); assert (sourcePackage != null); return sourcePackage; } /** * Gets the name of the C++ type for a proxy instance. * * @param clazz the source Java interface * * @return corresponding C++ type name */ private String getCppClassName(Class clazz) { String prefix; if (baseInterfaces.contains(clazz)) { prefix = basePrefix; } else { prefix = genPrefix; } return ReflectUtil.getUnqualifiedClassName(clazz).replaceFirst( prefix, "Proxy"); } /** * Gets the name of the C++ type used to return a proxy instance by * reference. * * @param clazz the source Java interface * * @return corresponding C++ type name */ private String getCppRefName(Class clazz) { return "Shared" + getCppClassName(clazz); } private String getCppReturnTypeName(Method method) { Class returnType = method.getReturnType(); if (Collection.class.isAssignableFrom(returnType)) { // strip off "get" String attrName = method.getName().substring(3); // determine the name of the class on the other end of the // association RefClass refClass = toJmiClass(method.getDeclaringClass()); MofClass mofClass = (MofClass) refClass.refMetaObject(); for (Object obj : mofClass.getContents()) { if (obj instanceof Reference) { Reference reference = (Reference) obj; String endName = reference.getReferencedEnd().getName(); if (endName.equalsIgnoreCase(attrName)) { return "SharedProxy" + reference.getReferencedEnd().getType().getName(); } } if (obj instanceof Attribute) { Attribute attribute = (Attribute) obj; if (attribute.getName().equalsIgnoreCase(attrName)) { return "SharedProxy" + attribute.getType().getName(); } } } } else if (RefEnum.class.isAssignableFrom(returnType)) { return ReflectUtil.getUnqualifiedClassName(returnType); } CppTypeInfo cppTypeInfo = cppTypeMap.get(returnType); if (cppTypeInfo != null) { return cppTypeInfo.cppTypeName; } return getCppRefName(returnType); } private CppTypeInfo getCppParameterTypeInfo(Class parameterType) { CppTypeInfo cppTypeInfo = cppTypeMap.get(parameterType); if (cppTypeInfo != null) { return cppTypeInfo; } throw new AssertionError("Unsupported type: " + parameterType); } /** * Decides whether a Java method is a getter for a JMI attribute. We ignore * all others. * * @param method the Java method * * @return true iff we consider it a getter */ private boolean isGetter(Method method) { String methodName = method.getName(); return (methodName.startsWith("get") || methodName.startsWith("is")) && (method.getParameterTypes().length == 0); } /** * Decides whether a Java method is setter for a JMI attribute that should * be proxied. Currently setter support is limited to properties with names * that begin with "result" and that are a primitive type, a type that boxes * a primitive (e.g. {@link Long}), or {@link String}. We ignore all methods * that don't match. * * @param method the Java method * * @return true iff we consider it a setter */ private boolean isSetter(Method method) { String methodName = method.getName(); return methodName.startsWith("setResult") && (method.getReturnType() != Void.class) && (method.getParameterTypes().length == 1) && cppTypeMap.containsKey(method.getParameterTypes()[0]); } private String getJavaTypeSignature(Class clazz) { String s = javaTypeMap.get(clazz); if (s != null) { return s; } return "L" + clazz.getName().replace('.', '/') + ";"; } private void generateClassDeclaration(Class clazz) { pw.print("class "); pw.print(getCppClassName(clazz)); pw.println(";"); pw.print("typedef JniProxyIter<"); pw.print(getCppClassName(clazz)); pw.print("> "); pw.print(getCppRefName(clazz)); pw.println(";"); } private void generateStaticDefinitions(Class clazz) { Method [] methods = clazz.getDeclaredMethods(); methods = toSortedArray(methods); for (int i = 0; i < methods.length; ++i) { if (isGetter(methods[i]) || isSetter(methods[i])) { pw.print("jmethodID "); pw.print(getCppClassName(clazz)); pw.print("::meth_"); pw.print(methods[i].getName()); pw.println(" = 0;"); } } } private void generateStaticInitialization(Class clazz) { pw.print("jClass = pEnv->FindClass(\""); pw.print(clazz.getName().replace('.', '/')); pw.println("\");"); pw.print("visitTbl.addMethod("); pw.print("jClass,"); pw.print( "JniProxyVisitTable<" + visitorClassName + ">::SharedVisitorMethod("); pw.print( "new JniProxyVisitTable<" + visitorClassName + ">::VisitorMethodImpl<"); pw.print(getCppClassName(clazz)); pw.println(">));"); Method [] methods = clazz.getDeclaredMethods(); methods = toSortedArray(methods); for (int i = 0; i < methods.length; ++i) { if (isGetter(methods[i])) { pw.print(getCppClassName(clazz)); pw.print("::meth_"); pw.print(methods[i].getName()); pw.print(" = pEnv->GetMethodID(jClass,\""); pw.print(methods[i].getName()); pw.print("\",\"()"); pw.print(getJavaTypeSignature(methods[i].getReturnType())); pw.println("\");"); } else if (isSetter(methods[i])) { pw.print(getCppClassName(clazz)); pw.print("::meth_"); pw.print(methods[i].getName()); pw.print(" = pEnv->GetMethodID(jClass,\""); pw.print(methods[i].getName()); pw.print("\",\"("); pw.print( getJavaTypeSignature(methods[i].getParameterTypes()[0])); pw.println(")V\");"); } } pw.println(); } private void generateVisitDeclaration(Class clazz) { // Visitor methods are defined to call a generic notification method // which can be overridden by implementations. This means // implementation only need to override visitors for classes of // interest, and for others they can decide whether to fail, ignore, or // take some other action. pw.print("virtual void visit("); pw.print(getCppClassName(clazz)); pw.println(" &)"); pw.println("{ unhandledVisit(); }"); } /** * Finds the JMI class corresponding to a Java interface. * * @param clazz the Java interface * * @return the corresponding JMI class, or null if clazz not in set of * interfaces to be generated */ private RefClass toJmiClass(Class clazz) { return javaToJmiMap.get(clazz); } //~ Inner Classes ---------------------------------------------------------- private static class CppTypeInfo { public final String cppTypeName; public final boolean isPrimitive; public final String boxingHelperMethod; public final String unboxingHelperMethod; protected CppTypeInfo(String cppTypeName) { this.cppTypeName = cppTypeName; this.isPrimitive = true; this.boxingHelperMethod = null; this.unboxingHelperMethod = null; } protected CppTypeInfo( String cppTypeName, String boxingHelperMethod, String unboxingHelperMethod) { this.cppTypeName = cppTypeName; this.isPrimitive = false; this.boxingHelperMethod = boxingHelperMethod; this.unboxingHelperMethod = unboxingHelperMethod; } } } // End ProxyGen.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/codegen/CppEnumGen.java0000444000175000017500000001101411173714170026242 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/CppEnumGen.java#15 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog.codegen; import java.io.*; import java.lang.reflect.*; import java.util.*; // TODO jvs 28-April-2004: move this to a repos-independent codegen utility // package and add a main method so it can be used from ant; this is just a // temporary parking space /** * CppEnumGen is a tool for generating a C++ enumeration based on the public * static final data members of a Java class. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/codegen/CppEnumGen.java#15 $ */ public class CppEnumGen { //~ Instance fields -------------------------------------------------------- private PrintWriter pw; //~ Constructors ----------------------------------------------------------- /** * Creates a new CppEnumGen. * * @param pw PrintWriter to which enumeration definitions should be written */ public CppEnumGen(PrintWriter pw) { this.pw = pw; } //~ Methods ---------------------------------------------------------------- /** * Generates a single enumeration. Enumeration values (and their names) is * based on the subset of non-inherited public static final data members * contained by enumClass and having exact type enumSymbolType. Enumeration * order (and hence implied ordinals) is on the current locale's collation * order for the enum field names. This ordering may not hold in the future, * so no C++ code should be written which depends on the current * deterministic ordering. * *

TODO: Support integer ordinals. Also, we'd prefer to preserve the * original metamodel ordering in order to relax the ordering condition * above. * * @param enumName name to give C++ enum * @param enumClass Java class to be interpreted as an enumeration; this * class's name is used as the enumeration name * @param enumSymbolType Java class used to determine enumeration membership */ public void generateEnumForClass( String enumName, Class enumClass, Class enumSymbolType) throws Exception { List symbols = new ArrayList(); Field [] fields = enumClass.getDeclaredFields(); for (int i = 0; i < fields.length; ++i) { Field field = fields[i]; Class fieldType = field.getType(); if (!(fieldType.equals(enumSymbolType))) { continue; } symbols.add(field.getName()); } // Force deterministic ordering Collections.sort(symbols); pw.print("enum "); pw.print(enumName); pw.println(" {"); Iterator iter = symbols.iterator(); while (iter.hasNext()) { String symbol = iter.next(); pw.print(" "); pw.print(symbol); if (iter.hasNext()) { pw.print(","); } pw.println(); } pw.println("};"); pw.println(); // TODO jvs 28-April-2004: declare as extern rather than static pw.print("static std::string "); pw.print(enumName); pw.print("_names[] = {"); iter = symbols.iterator(); while (iter.hasNext()) { String symbol = iter.next(); pw.print('"'); pw.print(symbol); pw.print('"'); pw.print(","); } pw.println("\"\"};"); pw.println(); } } // End CppEnumGen.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoRepos.java0000444000175000017500000002757011173714170025245 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoRepos.java#36 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.util.*; import javax.jmi.reflect.*; import net.sf.farrago.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.netbeans.api.mdr.*; /** * FarragoRepos represents a loaded repository containing Farrago metadata. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoRepos.java#36 $ */ public interface FarragoRepos extends FarragoAllocation, FarragoMetadataFactory { //~ Methods ---------------------------------------------------------------- // TODO: SWZ: 2008-03-26: Transition all red-zone code to getEnkiMdrRepos() // then either remove getMdrRepos() or else change it's return type to // EnkiMDRepository and migrate everyone back. /** * @return MDRepository storing this Farrago repository */ public MDRepository getMdrRepos(); /** * Returns an EnkiMDRepository storing this Farrago repository. This method * returns the same instance of {@link #getMdrRepos()}. * * @return EnkiMDRepository storing this Farrago repository */ public EnkiMDRepository getEnkiMdrRepos(); /** * @return model graph for repository metamodel */ public JmiModelGraph getModelGraph(); /** * @return model view for repository metamodel */ public JmiModelView getModelView(); /** * @return root package for transient metadata */ public FarragoPackage getTransientFarragoPackage(); /** * @return CwmCatalog representing this FarragoRepos */ public CwmCatalog getSelfAsCatalog(); /** * @return maximum identifier length in characters */ public int getIdentifierPrecision(); /** * @return element describing the configuration parameters */ public FemFarragoConfig getCurrentConfig(); /** * @return the name of the default {@link java.nio.charset.Charset} for this * repository */ public String getDefaultCharsetName(); /** * @return the name of the default collation name for this repository. The * value is of the form charset$locale$strength, as per {@link * org.eigenbase.sql.parser.SqlParserUtil#parseCollation(String)}. The * default is "ISO-8859-1$en_US". */ public String getDefaultCollationName(); /** * @return true iff Fennel support should be used */ public boolean isFennelEnabled(); /** * Formats the fully-qualified localized name for an existing object, * including its type. * *

Calling {@code getLocalizedObjectName(e)} is identical to calling * {@code getLocalizedObjectName(e, e.refClass())}.

* * @param modelElement catalog object * * @return localized name */ public String getLocalizedObjectName( CwmModelElement modelElement); /** * Formats the localized name for an unqualified typeless object. * * @param name object name * * @return localized name */ public String getLocalizedObjectName( String name); /** * Formats the fully-qualified localized name for an existing object. * * @param modelElement catalog object * @param refClass if non-null, use this as the type of the object, e.g. * "table SCHEMA.TABLE"; if null, don't include type (e.g. just * "SCHEMA.TABLE") * * @return localized name */ public String getLocalizedObjectName( CwmModelElement modelElement, RefClass refClass); /** * Formats the fully-qualified localized name for an object that may not * exist yet. * * @param qualifierName name of containing object, or null for unqualified * name * @param objectName name of object * @param refClass if non-null, the object type to use in the name; if null, * no type is prepended * * @return localized name */ public String getLocalizedObjectName( String qualifierName, String objectName, RefClass refClass); /** * Looks up the localized name for a class of metadata. * * @param refClass class of metadata, e.g. CwmTableClass * * @return localized name, e.g. "table" */ public String getLocalizedClassName(RefClass refClass); /** * Looks up a catalog by name. * * @param catalogName name of catalog to find * * @return catalog definition, or null if not found */ public CwmCatalog getCatalog(String catalogName); /** * Gets an element's tag. * * @param element the tagged element * @param tagName name of tag to find * * @return tag, or null if not found * * @deprecated use getTagAnnotation instead */ public CwmTaggedValue getTag( CwmModelElement element, String tagName); /** * Tags an element. * * @param element the element to tag * @param tagName name of tag to create; if a tag with this name already * exists, it will be updated * @param tagValue value to set * * @deprecated use setTagAnnotationValue instead */ public void setTagValue( CwmModelElement element, String tagName, String tagValue); /** * Gets a value tagged to an element. * * @param element the tagged element * @param tagName name of tag to find * * @return tag value, or null if not found * * @deprecated use getTagAnnotationValue instead */ public String getTagValue( CwmModelElement element, String tagName); /** * Gets an element's annotation tag. * * @param element the tagged element * @param tagName name of tag to find * * @return tag, or null if not found */ public FemTagAnnotation getTagAnnotation( FemAnnotatedElement element, String tagName); /** * Tags an annotated element. * * @param element the element to tag * @param tagName name of tag to create; if a tag with this name already * exists, it will be updated * @param tagValue value to set */ public void setTagAnnotationValue( FemAnnotatedElement element, String tagName, String tagValue); /** * Gets a value tagged to an annotated element. * * @param element the tagged element * @param tagName name of tag to find * * @return tag value, or null if not found */ public String getTagAnnotationValue( FemAnnotatedElement element, String tagName); /** * Defines localization for this repository. * * @param bundles list of {@link java.util.ResourceBundle} instances to add * for */ public void addResourceBundles(List bundles); /** * Returns an instance of FarragoReposTxnContext for use in executing * transactions against this repository without automatic repository session * management. Equivalent to {@link #newTxnContext(boolean) * newTxnContext(false)}. * * @return an instance of FarragoReposTxnContext for use in executing * transactions against this repository */ public FarragoReposTxnContext newTxnContext(); /** * Returns an instance of FarragoReposTxnContext for use in executing * transactions against this repository. If the manageReposSession parameter * is true, the returned {@link FarragoReposTxnContext} is responsible for * managing repository sessions. Otherwise the caller is responsible for * managing the repository session. * * @param manageReposSession if true, the FarragoReposTxnContext manages the * repository session * * @return an instance of FarragoReposTxnContext for use in executing * transactions against this repository */ public FarragoReposTxnContext newTxnContext(boolean manageReposSession); /** * Begins a session on the metadata repository. * * @see #newTxnContext(boolean) */ public void beginReposSession(); /** * Begins a metadata transaction on the repository. In most cases, this * should be done by creating and manipulating an instance of {@link * FarragoReposTxnContext} instead. * * @param writable true for read/write; false for read-only */ public void beginReposTxn(boolean writable); /** * Ends a metadata transaction on the repository. * * @param rollback true to rollback; false to commit */ public void endReposTxn(boolean rollback); /** * Ends a session on the metadata repository. * * @see #newTxnContext(boolean) */ public void endReposSession(); /** * Returns the metadata factory for a particular plugin. In particular, * getMetadataFactory("Fem") returns this. * * @param prefix The name of the prefix which identifies the metadata * factory */ Object getMetadataFactory(String prefix); /** * Returns the an accessor for a sequence stored in the repository * * @param mofId the identifier for the sequence */ public FarragoSequenceAccessor getSequenceAccessor(String mofId); /** * Returns the input string with property values substituted for variables * of the form ${VARNAME}, such as that done by {@link * FarragoProperties#expandProperties(String)}.. * * @param value String we want to expand * * @return expanded string, if value(s) were known */ public String expandProperties(String value); /** * Returns a collection of all instances of a given class. * *

This method has the same effect as {@link RefClass#refAllOfClass()}, * but is preferable because it returns a typed collection. */ public Collection allOfClass(Class clazz); /** * Returns a collection of all instances of a given type. * *

This method has the same effect as {@link RefClass#refAllOfType()}, * but is preferable because it returns a typed collection. */ public Collection allOfType(Class clazz); /** * Verifies the integrity of the repository. * * @param refObj a single object to check (independent of related objects) * or null to check the entire repository * * @return list of violations (empty list indicates integrity check passed) */ public List verifyIntegrity( RefObject refObj); /** * Returns the FarragoModelLoader for this repos. May return null if not * supported by implementation. */ public FarragoModelLoader getModelLoader(); } // End FarragoRepos.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoCatalogUtil.java0000444000175000017500000023002311173714170026352 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoCatalogUtil.java#58 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.lang.reflect.*; import java.sql.Timestamp; import java.util.*; import javax.jmi.reflect.*; import net.sf.farrago.cwm.behavioral.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.keysindexes.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.cwm.relational.enumerations.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.eigenbase.sql.*; import org.eigenbase.sql.parser.*; import org.eigenbase.util.*; /** * Static utilities for accessing the Farrago catalog. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoCatalogUtil.java#58 $ */ public abstract class FarragoCatalogUtil { //~ Enums ------------------------------------------------------------------ /** * Enumeration of the different type of row count statistics */ private enum RowCountStatType { ROW_COUNT, DELETED_ROW_COUNT, ANALYZE_ROW_COUNT } //~ Methods ---------------------------------------------------------------- /** * Sets default attributes for a new catalog instance. * * @param repos repository in which catalog is stored * @param catalog catalog to initialize */ public static void initializeCatalog( FarragoRepos repos, CwmCatalog catalog) { catalog.setDefaultCharacterSetName( SaffronProperties.instance().defaultCharset.get()); catalog.setDefaultCollationName( SaffronProperties.instance().defaultCollation.get()); } /** * Calculates the number of parameters expected by a routine. For functions, * this is different from the number of parameters defined in the * repository, because CWM represents the return type by appending an extra * parameter. */ public static int getRoutineParamCount(FemRoutine routine) { int nParams = routine.getParameter().size(); if (routine.getType() == ProcedureTypeEnum.FUNCTION) { --nParams; } return nParams; } /** * Determines whether a routine is a constructor method. * * @param routine routine in question * * @return true if routine is a constructor method */ public static boolean isRoutineConstructor(FemRoutine routine) { // TODO: once we support non-constructor methods return isRoutineMethod(routine); } /** * Determines whether a routine is a method. * * @param routine routine in question * * @return true if routine is a method */ public static boolean isRoutineMethod(FemRoutine routine) { return !routine.getSpecification().getOwner().equals(routine); } /** * Sets the specification for a routine. * * @param repos repository storing the routine definition * @param routine new routine * @param typeDef owning type if a method, else null */ public static void setRoutineSpecification( FarragoRepos repos, FemRoutine routine, FemUserDefinedType typeDef) { CwmOperation operation = repos.newCwmOperation(); if (typeDef == null) { operation.setOwner(routine); } else { operation.setOwner(typeDef); } operation.setName(routine.getName()); operation.setAbstract(false); routine.setSpecification(operation); } /** * Determines whether an index is temporary. * * @param index the index in question * * @return true if temporary */ public static boolean isIndexTemporary(CwmSqlindex index) { return getIndexTable(index).isTemporary(); } /** * Gets the table on which an index is defined. * * @param index the index in question * * @return containing table */ public static CwmTable getIndexTable(CwmSqlindex index) { return (CwmTable) index.getSpannedClass(); } /** * Gets the {@link FemLocalTable} on which a {@link FemLocalIndex} is * defined. * * @param index the index in question * * @return containing table */ public static FemLocalTable getIndexTable(FemLocalIndex index) { return (FemLocalTable) index.getSpannedClass(); } /** * Determines whether an index implements its table's primary key. * * @param index the index in question * * @return true if is the primary key index */ public static boolean isIndexPrimaryKey(FemLocalIndex index) { return index.getName().startsWith( "SYS$CONSTRAINT_INDEX$SYS$PRIMARY_KEY"); } /** * Determines whether an index implements either a primary key or a unique * constraint * * @param index the index in question * * @return true if is either the primary key index or a unique constraint * index */ public static boolean isIndexUnique(FemLocalIndex index) { return ((CwmIndex) index).isUnique(); } /** * Determines whether an index implements an internal deletion index. * * @param index the index in question * * @return true if index is the deletion index */ public static boolean isDeletionIndex(FemLocalIndex index) { return index.getName().startsWith("SYS$DEL"); } /** * Finds the unique key constraints for a table. * * @param table the table of interest * * @return a list of unique key constraints, or an empty list if none is * defined */ public static List getUniqueKeyConstraints( CwmClassifier table) { List listOfConstraints = new ArrayList(); for (Object obj : table.getOwnedElement()) { if (obj instanceof FemUniqueKeyConstraint) { listOfConstraints.add((FemUniqueKeyConstraint) obj); } } return listOfConstraints; } /** * Finds the primary key for a table. * * @param table the table of interest * * @return the PrimaryKey constraint, or null if none is defined */ public static FemPrimaryKeyConstraint getPrimaryKey(CwmClassifier table) { for (CwmModelElement obj : table.getOwnedElement()) { if (obj instanceof FemPrimaryKeyConstraint) { return (FemPrimaryKeyConstraint) obj; } } return null; } /** * Returns a bitmap with bits set for any column from a table that is part * of either a primary key or a unique constraint * * @param table the table of interest * * @return bitmap with set bits */ public static BitSet getUniqueKeyCols(CwmClassifier table) { BitSet uniqueCols = new BitSet(); // first retrieve the columns from the primary key FemPrimaryKeyConstraint primKey = FarragoCatalogUtil.getPrimaryKey(table); if (primKey != null) { addKeyCols((List) primKey.getFeature(), uniqueCols); } // then, loop through each unique constraint List uniqueConstraints = FarragoCatalogUtil.getUniqueKeyConstraints(table); for (FemUniqueKeyConstraint uniqueConstraint : uniqueConstraints) { addKeyCols((List) uniqueConstraint.getFeature(), uniqueCols); } return uniqueCols; } private static void addKeyCols(List keyCols, BitSet keys) { for (FemAbstractColumn keyCol : keyCols) { keys.set(keyCol.getOrdinal()); } } /** * Determines whether a table contains a unique key * * @param table the table of interest * * @return true if the table has a unique key */ public static boolean hasUniqueKey(CwmClassifier table) { for (CwmModelElement obj : table.getOwnedElement()) { if ((obj instanceof FemPrimaryKeyConstraint) || (obj instanceof FemUniqueKeyConstraint)) { return true; } } return false; } /** * Finds the clustered index storing a table's data. * * @param repos repository storing the table definition * @param table the table to access * * @return clustered index or null if none */ public static FemLocalIndex getClusteredIndex( FarragoRepos repos, CwmClass table) { for (FemLocalIndex index : getTableIndexes(repos, table)) { if (index.isClustered()) { return index; } } return null; } /** * Finds all clustered indexes storing a table's data. * * @param repos repository storing the table definition * @param table the table to access * * @return list of clustered indexes or an empty list if none */ public static List getClusteredIndexes( FarragoRepos repos, CwmClass table) { ArrayList indexList = new ArrayList(); for (FemLocalIndex index : getTableIndexes(repos, table)) { if (index.isClustered()) { indexList.add(index); } } return indexList; } /** * Finds all unclustered indexes storing a table's data. * * @param repos repository storing the table definition * @param table the table to access * * @return list of clustered indexes or an empty list if none */ public static List getUnclusteredIndexes( FarragoRepos repos, CwmClass table) { ArrayList indexList = new ArrayList(); for (FemLocalIndex index : getTableIndexes(repos, table)) { if (!index.isClustered() && !isDeletionIndex(index)) { indexList.add(index); } } return indexList; } /** * Returns the index corresponding to the internal deletion index * * @param repos repository storing the table definition * @param table the table to access * * @return the deletion index if it exists, otherwise NULL */ public static FemLocalIndex getDeletionIndex( FarragoRepos repos, CwmClass table) { for (FemLocalIndex index : getTableIndexes(repos, table)) { if (isDeletionIndex(index)) { return index; } } return null; } /** * Gets the collection of indexes spanning a table. * * @param repos repository storing the table definition * @param table the table of interest * * @return index collection */ public static Collection getTableIndexes( final FarragoRepos repos, final CwmClass table) { // REVIEW: SWZ: 2008-02-11: The association IndexSpansClass is // between CwmClass and CwmIndex. However, Farrago never creates // any CwmIndex (or CqmSqlindex) instances, only FemLocalIndex // instances. Netbeans MDR doesn't generate generic types for return // values, but Enki does. Consider modifying calls to this method to // do the conversion as necessary. Or perhaps introduce a // getModelElementByType method. // REVIEW: SWZ: 2008-04-23: Force deterministic order onto the indexes. // Many unit tests end up depending on this for reliable ordering // of output. List result = new ArrayList(); for ( CwmIndex index : repos.getKeysIndexesPackage().getIndexSpansClass().getIndex( table)) { result.add((FemLocalIndex) index); } Collections.sort(result, JmiMofIdComparator.instance); return result; } /** * Sets the generated name for an index used to implement a constraint. * * @param repos repos storing index * @param constraint the constraint being implemented * @param index the index implementing the constraint */ public static void generateConstraintIndexName( FarragoRepos repos, FemAbstractUniqueConstraint constraint, CwmSqlindex index) { String name = "SYS$CONSTRAINT_INDEX$" + constraint.getName(); index.setName(uniquifyGeneratedName(repos, constraint, name)); } /** * Sets the generated name for an anonymous constraint. * * @param repos repos storing constraint * @param constraint the anonymous constraint */ public static void generateConstraintName( FarragoRepos repos, FemAbstractUniqueConstraint constraint) { String name; if (constraint instanceof FemPrimaryKeyConstraint) { name = "SYS$PRIMARY_KEY$" + constraint.getNamespace().getName(); } else { name = "SYS$UNIQUE_KEY$" + constraint.getNamespace().getName() + "$" + generateUniqueConstraintColumnList(constraint); } constraint.setName(uniquifyGeneratedName(repos, constraint, name)); } /** * Generated names are normally unique by construction. However, if they * exceed the name length limit, truncation could cause collisions. In that * case, we use repository object ID's to distinguish them. * * @param repos repos storing object * @param refObj object for which to construct name * @param name generated name * * @return uniquified name */ public static String uniquifyGeneratedName( FarragoRepos repos, RefObject refObj, String name) { if (name.length() <= repos.getIdentifierPrecision()) { return name; } String mofId = refObj.refMofId(); return name.substring( 0, repos.getIdentifierPrecision() - (mofId.length() + 1)) + "_" + mofId; } private static String generateUniqueConstraintColumnList( FemAbstractUniqueConstraint constraint) { StringBuilder sb = new StringBuilder(); Iterator iter = constraint.getFeature().iterator(); while (iter.hasNext()) { CwmColumn column = (CwmColumn) iter.next(); // TODO: deal with funny chars sb.append(column.getName()); if (iter.hasNext()) { sb.append("_"); } } return sb.toString(); } /** * Searches a collection of {@link CwmModelElement}s (or a subtype) by name. * * @param collection the collection to search * @param name name of element to find * * @return CwmModelElement found, or null if not found */ public static T getModelElementByName( Collection collection, String name) { for (T element : collection) { if (element.getName().equals(name)) { return element; } } return null; } /** * Searches a collection for a CwmModelElement by name and type. * * @param collection the collection to search * @param name name of element to find * @param clazz class which sought object must instantiate * * @return CwmModelElement found, or null if not found */ public static T getModelElementByNameAndType( Collection collection, String name, Class clazz) { for (CwmModelElement element : collection) { if (!element.getName().equals(name)) { continue; } if (clazz.isInstance(element)) { return clazz.cast(element); } } return null; } /** * @deprecated use typesafe version instead */ public static CwmModelElement getModelElementByNameAndType( Collection collection, String name, RefClass type) { return getModelElementByNameAndType( (Collection) collection, name, (Class) JmiObjUtil.getClassForRefClass(type)); } /** * Filters a collection for all {@link CwmModelElement}s of a given type. * * @param inCollection the collection to search * @param outCollection receives matching objects * @param type class which sought objects must instantiate * * @see Util#filter(List, java.lang.Class) */ public static void filterTypedModelElements( Collection inCollection, Collection outCollection, Class type) { for (CwmModelElement element : inCollection) { if (type.isInstance(element)) { outCollection.add(type.cast(element)); } } } /** * Indexes a collection of model elements by name. * * @param inCollection elements to be indexed * @param outMap receives indexed elements; key is name, value is element */ public static void indexModelElementsByName( Collection inCollection, Map outMap) { for (T element : inCollection) { outMap.put( element.getName(), element); } } /** * Looks up a schema by name in a catalog. * * @param catalog CwmCatalog to search * @param schemaName name of schema to find * * @return schema definition, or null if not found */ public static FemLocalSchema getSchemaByName( CwmCatalog catalog, String schemaName) { return getModelElementByNameAndType( catalog.getOwnedElement(), schemaName, FemLocalSchema.class); } /** * Determines whether a column may contain null values. This must be used * rather than directly calling CwmColumn.getIsNullable, because a column * which is part of a primary key or clustered index may not contain nulls * even when its definition says it can. * *

REVIEW jvs 7-July-2006: The statement above is no longer true; we now * store the derived nullability in isNullable, and remember the original * declared nullability in isDeclaredNullable. Maybe we should deprecate * this method now. * * @param repos repos storing column definition * @param column the column of interest * * @return whether nulls are allowed */ public static boolean isColumnNullable( FarragoRepos repos, CwmColumn column) { if (column.getIsNullable().equals(NullableTypeEnum.COLUMN_NO_NULLS)) { return false; } else { return true; } } /** * Gets the routine which implements a particular user-defined ordering, or * null if the ordering does not invoke a routine. * * @param udo user-defined ordering of interest * * @return invoked routine or null */ public static FemRoutine getRoutineForOrdering(FemUserDefinedOrdering udo) { Collection deps = udo.getOwnedElement(); if (deps.isEmpty()) { return null; } assert (deps.size() == 1); CwmDependency dep = (CwmDependency) deps.iterator().next(); assert (dep.getSupplier().size() == 1); return (FemRoutine) dep.getSupplier().iterator().next(); } /** * Constructs a fully qualified name for an object. * * @param element model element * * @return qualified identifier */ public static SqlIdentifier getQualifiedName(CwmModelElement element) { List names = new ArrayList(3); names.add(element.getName()); for ( CwmNamespace ns = element.getNamespace(); ns != null; ns = ns.getNamespace()) { names.add(ns.getName()); } Collections.reverse(names); String [] nameArray = names.toArray(new String[names.size()]); return new SqlIdentifier(nameArray, SqlParserPos.ZERO); } /** * Casts a {@link FemAbstractTypedElement} to the {@link FemSqltypedElement} * interface via a proxy. * * @param element element to cast * * @return cast result (a proxy) */ public static FemSqltypedElement toFemSqltypedElement( final FemAbstractTypedElement element) { Class [] interfaces = element.getClass().getInterfaces(); Class [] newInterfaces = new Class[interfaces.length + 1]; System.arraycopy(interfaces, 0, newInterfaces, 1, interfaces.length); newInterfaces[0] = FemSqltypedElement.class; return (FemSqltypedElement) Proxy.newProxyInstance( FarragoCatalogUtil.class.getClassLoader(), newInterfaces, new InvocationHandler() { // implement InvocationHandler public Object invoke( Object proxy, Method method, Object [] args) throws Throwable { if (method.getName().equals("getModelElement")) { return element; } // delegate by name Method delegateMethod = element.getClass().getMethod( method.getName(), method.getParameterTypes()); return delegateMethod.invoke(element, args); } }); } /** * Returns a collection of just the structural features of a classifier, * hiding other features such as operations. * * @param classifier to access * * @return list of structural features */ public static List getStructuralFeatures( CwmClassifier classifier) { return Util.filter( classifier.getFeature(), CwmStructuralFeature.class); } /** * Determines whether a UDF has a RETURNS TABLE clause. * * @param routine UDF * * @return true if RETURNS TABLE */ public static boolean isTableFunction(FemRoutine routine) { return !getStructuralFeatures(routine).isEmpty(); } /** * Returns the URL for a jar with all properties expanded. * * @param femJar jar to access * * @return expanded URL as a string */ public static String getJarUrl(FemJar femJar) { return FarragoProperties.instance().expandProperties(femJar.getUrl()); } /** * Finds the FemAuthId for a specified Authorization name. * * @param repos repository storing the Authorization Id * @param authName the input name used for this lookup * * @return repository element represents the authorization identifier */ public static FemAuthId getAuthIdByName( FarragoRepos repos, String authName) { return FarragoCatalogUtil.getModelElementByName( repos.allOfType(FemAuthId.class), authName); } /** * Looks up a user by name in a catalog. * * @param repos repos storing catalog * @param userName name of user to find * * @return user definition, or null if not found */ public static FemUser getUserByName( FarragoRepos repos, String userName) { return FarragoCatalogUtil.getModelElementByName( repos.allOfType(FemUser.class), userName); } /** * Looks up a role by name in a catalog. * * @param repos repos storing catalog * @param roleName name of role to find * * @return role definition, or null if not found */ public static FemRole getRoleByName( FarragoRepos repos, String roleName) { return FarragoCatalogUtil.getModelElementByName( repos.allOfType(FemRole.class), roleName); } /** * Creates a new grant on a ROLE with specified role name and associate it * to the grantor and grantee auth ids respectively. By default, the admin * option is set to false. The caller will have to set it on the grant * object returned. * * @param repos repository containing the objects * @param grantorName the creator of this grant * @param granteeName the receipient of this grant * @param roleName the role name of the authorization id to be granted by * this new grant * * @return new grant object */ public static FemGrant newRoleGrant( FarragoRepos repos, String grantorName, String granteeName, String roleName) { FemAuthId grantorAuthId; FemAuthId granteeAuthId; FemAuthId grantedRole; // create a creation grant and set its properties FemGrant grant; // Find the authId by name for grantor and grantee grantorAuthId = FarragoCatalogUtil.getAuthIdByName(repos, grantorName); granteeAuthId = FarragoCatalogUtil.getAuthIdByName(repos, granteeName); // Find the Fem role by name grantedRole = FarragoCatalogUtil.getAuthIdByName(repos, roleName); if (grantedRole == null) { // TODO: throw res.instance().newRoleNameInvalid(roleName); } grant = newElementGrant( repos, grantorAuthId, granteeAuthId, grantedRole); // set properties specific for a grant of a role grant.setAction(PrivilegedActionEnum.INHERIT_ROLE.toString()); grant.setWithGrantOption(false); return grant; } /** * Creates a grant on a specified repos element, with AuthId's specified as * strings. * * @param repos repository storing the objects * @param grantorName the creator of this grant * @param granteeName the recipient of this grant * @param grantedObject element being granted * * @return grant a grant object */ public static FemGrant newElementGrant( FarragoRepos repos, String grantorName, String granteeName, CwmModelElement grantedObject) { FemAuthId grantorAuthId; FemAuthId granteeAuthId; // Find the authId by name for grantor and grantee grantorAuthId = FarragoCatalogUtil.getAuthIdByName(repos, grantorName); granteeAuthId = FarragoCatalogUtil.getAuthIdByName(repos, granteeName); return newElementGrant( repos, grantorAuthId, granteeAuthId, grantedObject); } /** * Create a new grant for an element, with AuthId's specified as repository * objects. * * @param repos repository storing the objects * @param grantorAuthId the creator of this grant * @param granteeAuthId the receipient of this grant * @param grantedObject element being granted * * @return new grant object */ public static FemGrant newElementGrant( FarragoRepos repos, FemAuthId grantorAuthId, FemAuthId granteeAuthId, CwmModelElement grantedObject) { // create a privilege object and set its properties FemGrant grant = repos.newFemGrant(); // TODO: to grant.setHierarchyOption(hierarchyOption); // associate the grant with the grantor and grantee grant.setGrantor(grantorAuthId); grant.setGrantee(granteeAuthId); grant.setElement(grantedObject); return grant; } /** * Creates a new grant representing ownership of an object by its creator. * * @param repos repository storing the objects * @param grantorName the name of the creator of the grant * @param granteeName the name of the grantee of the grant * @param grantedObject element being created * * @return new grant object */ public static FemGrant newCreationGrant( FarragoRepos repos, String grantorName, String granteeName, CwmModelElement grantedObject) { // Find the authId by name for grantor and grantee FemAuthId grantorAuthId = FarragoCatalogUtil.getAuthIdByName(repos, grantorName); FemAuthId granteeAuthId = FarragoCatalogUtil.getAuthIdByName(repos, granteeName); assert (grantorAuthId != null); assert (granteeAuthId != null); return newCreationGrant( repos, grantorAuthId, granteeAuthId, grantedObject); } /** * Creates a new grant representing ownership of an object by its creator. * * @param repos repository storing the objects * @param grantorAuthId a FemAuthId representing the creator of the grant * @param granteeAuthId a FemAuthId representing the grantee of the grant * @param grantedObject element being created * * @return new grant object */ public static FemGrant newCreationGrant( FarragoRepos repos, FemAuthId grantorAuthId, FemAuthId granteeAuthId, CwmModelElement grantedObject) { // create a creation grant and set its properties FemGrant grant = repos.newFemGrant(); // set the privilege name (i.e. action) and properties. grant.setAction(PrivilegedActionEnum.CREATION.toString()); grant.setWithGrantOption(false); // associate the grant with the grantor and grantee respectively grant.setGrantor(grantorAuthId); grant.setGrantee(granteeAuthId); grant.setElement(grantedObject); return grant; } /** * Determines the allowed access for a table * * @param table Repository table * * @return Access type of the table */ public static SqlAccessType getTableAllowedAccess(CwmNamedColumnSet table) { SqlAccessType allowedAccess; if (table instanceof FemBaseColumnSet) { FemBaseColumnSet cs = (FemBaseColumnSet) table; String accessNames = cs.getAllowedAccess(); if (accessNames != null) { allowedAccess = SqlAccessType.create(accessNames); } else { allowedAccess = SqlAccessType.ALL; } } else if (table instanceof CwmView) { CwmView view = (CwmView) table; allowedAccess = view.isReadOnly() ? SqlAccessType.READ_ONLY : SqlAccessType.ALL; } else { allowedAccess = SqlAccessType.ALL; } return allowedAccess; } /** * Retrieves the current and deleted row counts for an abstract column set, * optionally based on a label setting. * * @param table the abstract column set * @param labelTimestamp creation timestamp of the label setting that * determines which row counts to retrieve; null if there is no label * setting * @param rowCounts the row counts to be returned; the first element in the * array is the current row count and the second is the deleted row count */ public static void getRowCounts( FemAbstractColumnSet table, Timestamp labelTimestamp, Long [] rowCounts) { // If there's no label setting, retrieve the latest stats. if (labelTimestamp == null) { rowCounts[0] = table.getRowCount(); rowCounts[1] = table.getDeletedRowCount(); return; } // Older catalog versions and newly created tables only store // the row counts directly in the columnSet record so there won't // be separate row count stat records yet. List rowCountStatsList = table.getRowCountStats(); if (rowCountStatsList.isEmpty()) { rowCounts[0] = table.getRowCount(); rowCounts[1] = table.getDeletedRowCount(); return; } else { // Work backwards through the list until we find the first set // of row counts that are older than the label timestamp passed // in. for (int i = rowCountStatsList.size() - 1; i >= 0; i--) { FemRowCountStatistics stats = rowCountStatsList.get(i); Timestamp statTime = getMaxTimestamp(table, stats); if ((statTime == null) || (statTime.compareTo(labelTimestamp) < 0)) { rowCounts[0] = stats.getRowCount(); rowCounts[1] = stats.getDeletedRowCount(); return; } } } // If we reach this point, then the current set of row counts were all // generated after the label setting, so no row count stats are // available. rowCounts[0] = null; rowCounts[1] = null; } /** * Returns the max of the dml and analyze timestamps stored in a row count * statistics record. If both timestamps are null, returns null. * * @param table the abstract column set corresponding to the row count stats * record * @param stats the row count stats record * * @return maximum of the dml and analyze timestamps or null if both * timestamps are null */ private static Timestamp getMaxTimestamp( FemAbstractColumnSet table, FemRowCountStatistics stats) { String dmlTime = stats.getDmlTimestamp(); String analyzeTime = stats.getAnalyzeTimestamp(); if (analyzeTime == null) { if (dmlTime == null) { return null; } else { return Timestamp.valueOf(dmlTime); } } if (dmlTime == null) { return Timestamp.valueOf(analyzeTime); } Timestamp dmlTimestamp = Timestamp.valueOf(dmlTime); Timestamp analyzeTimestamp = Timestamp.valueOf(analyzeTime); if (dmlTimestamp.compareTo(analyzeTimestamp) > 0) { return dmlTimestamp; } else { return analyzeTimestamp; } } /** * Updates the current and deleted row counts for an abstract column set, * creating new row count stat records as needed. * * @param table the abstract column set * @param rowCount the current row count * @param deletedRowCount the deleted row count * @param repos repository */ public static void updateRowCounts( FemAbstractColumnSet table, long rowCount, long deletedRowCount, FarragoRepos repos) { List rowCounts = new ArrayList(); RowCountStat rowCountStat = new RowCountStat(RowCountStatType.ROW_COUNT, rowCount); rowCounts.add(rowCountStat); rowCountStat = new RowCountStat( RowCountStatType.DELETED_ROW_COUNT, deletedRowCount); rowCounts.add(rowCountStat); updateRowCounts(table, rowCounts, repos); } /** * Updates various row counts for an abstract column set, creating new row * count stat records as needed. * * @param table the abstract column set * @param rowCounts list of row counts to be updated * @param repos repository */ public static void updateRowCounts( FemAbstractColumnSet table, List rowCounts, FarragoRepos repos) { List rowCountStatsList = table.getRowCountStats(); // There will be no rowCountStats record if this table was migrated // from an earlier version. So, first migrate over the existing row // count stats stored in the table record. Note that even in the // case where there are no stats yet, we'll create an initial record, // which will be overwritten with the new stats further below. if (rowCountStatsList.isEmpty()) { FemRowCountStatistics rowCountStats = repos.newFemRowCountStatistics(); rowCountStats.setColumnSet(table); rowCountStats.setRowCount(table.getRowCount()); rowCountStats.setDeletedRowCount(table.getDeletedRowCount()); rowCountStats.setAnalyzeRowCount(table.getLastAnalyzeRowCount()); rowCountStats.setAnalyzeTimestamp(table.getAnalyzeTime()); // leave the dml timestamp set to null because we don't really // know what it is // add the new record to our list rowCountStatsList = new ArrayList(); rowCountStatsList.add(rowCountStats); } // Determine if we need to create a new row count stats record or can // reuse the latest one. We can reuse the latest if those stats were // created after the newest label was created. When determining the // timestamp of the row count stats, take the maximum of the dml and // analyze timestamps. FemRowCountStatistics rowCountStats = rowCountStatsList.get(rowCountStatsList.size() - 1); Timestamp newestLabelTimestamp = getNewestLabelCreationTimestamp(repos); Timestamp maxTimestamp = getMaxTimestamp(table, rowCountStats); if ((newestLabelTimestamp == null) || (maxTimestamp == null) || (newestLabelTimestamp.compareTo(maxTimestamp) < 0)) { setNewRowCounts(table, rowCountStats, rowCounts); } else { FemRowCountStatistics newRowCountStats = repos.newFemRowCountStatistics(); newRowCountStats.setColumnSet(table); // initialize the record with the values from the previous // record newRowCountStats.setDmlTimestamp(rowCountStats.getDmlTimestamp()); newRowCountStats.setRowCount(rowCountStats.getRowCount()); newRowCountStats.setDeletedRowCount( rowCountStats.getDeletedRowCount()); newRowCountStats.setAnalyzeTimestamp( rowCountStats.getAnalyzeTimestamp()); newRowCountStats.setAnalyzeRowCount( rowCountStats.getAnalyzeRowCount()); // now, set the new, current values setNewRowCounts(table, newRowCountStats, rowCounts); } } /** * Updates the row count statistic for an abstract column set * * @param columnSet the column set whose row count will be updated * @param rowCount number of rows returned by column set * @param updateRowCount if true, the {@link * FemAbstractColumnSet#setRowCount(Long)} property is updated. * @param updateAnalyzeRowCount if true, the {@link * FemAbstractColumnSet#setLastAnalyzeRowCount(Long)} property is updated * * @deprecated */ public static void updateRowCount( FemAbstractColumnSet columnSet, Long rowCount, boolean updateRowCount, boolean updateAnalyzeRowCount) { if (updateAnalyzeRowCount) { columnSet.setAnalyzeTime(createTimestamp()); columnSet.setLastAnalyzeRowCount(rowCount); } if (updateRowCount) { columnSet.setRowCount(rowCount); } } /** * Updates the row count statistic for an abstract column set, creating new * row count stat records, as needed. * * @param columnSet the column set whose row count will be updated * @param rowCount number of rows returned by column set * @param updateRowCount if true, the current row count is updated * @param updateAnalyzeRowCount if true, the analyze row count is updated */ public static void updateRowCount( FemAbstractColumnSet columnSet, Long rowCount, boolean updateRowCount, boolean updateAnalyzeRowCount, FarragoRepos repos) { List rowCounts = new ArrayList(); RowCountStat rowCountStat; if (updateAnalyzeRowCount) { rowCountStat = new RowCountStat( RowCountStatType.ANALYZE_ROW_COUNT, rowCount); rowCounts.add(rowCountStat); } if (updateRowCount) { rowCountStat = new RowCountStat(RowCountStatType.ROW_COUNT, rowCount); rowCounts.add(rowCountStat); } updateRowCounts(columnSet, rowCounts, repos); } /** * Retrieves the page count statistic for a local index, taking into * consideration the current label setting. * * @param index the index whose page count will be retrieved * @param labelTimestamp creation timestamp of the label setting that * determines which page count to retrieve; null if there is no label * setting * * @return the page count for the index */ public static Long getPageCount( FemLocalIndex index, Timestamp labelTimestamp) { // If there's no label setting, retrieve the latest stat. if (labelTimestamp == null) { return index.getPageCount(); } // Older catalog versions only store the page count directly in // the index record so there won't be separate page count // stat records yet. List indexStatsList = index.getIndexStats(); if (indexStatsList.isEmpty()) { return index.getPageCount(); } else { // Work backwards through the list until we find the first set // of stats that are older than the label timestamp passed // in. for (int i = indexStatsList.size() - 1; i >= 0; i--) { FemIndexStatistics stats = indexStatsList.get(i); Timestamp statTime = Timestamp.valueOf(stats.getAnalyzeTime()); if (statTime.compareTo(labelTimestamp) < 0) { return stats.getPageCount(); } } } // The current set of stats were all generated after the label setting, // so no index page count is available. return null; } /** * Updates the page count statistic for a local index in the index record. * * @param index the index whose page count will be updated * @param pageCount number of pages on disk used by index * * @deprecated */ public static void updatePageCount( FemLocalIndex index, Long pageCount) { index.setAnalyzeTime(createTimestamp()); index.setPageCount(pageCount); } /** * Updates the page count statistic for a local index, creating new index * stat records as needed. * * @param index the index whose page count will be updated * @param pageCount number of pages on disk used by index * @param repos repository */ public static void updatePageCount( FemLocalIndex index, Long pageCount, FarragoRepos repos) { String currTimestamp = createTimestamp(); List indexStatsList = index.getIndexStats(); // There will be no indexStats record if this index was migrated // from an earlier version. So, first migrate over the existing page // count stat stored in the index record. In the case where there's // no stat yet, we'll just create the initial record. boolean noExistingStat = false; if (indexStatsList.isEmpty()) { FemIndexStatistics indexStats = repos.newFemIndexStatistics(); indexStats.setLocalIndex(index); if (index.getAnalyzeTime() == null) { noExistingStat = true; } else { indexStats.setPageCount(index.getPageCount()); indexStats.setAnalyzeTime(index.getAnalyzeTime()); } // Add the new record to the list of stats indexStatsList = new ArrayList(); indexStatsList.add(indexStats); } // Determine whether to update the latest record or create a new one. FemIndexStatistics indexStats = indexStatsList.get(indexStatsList.size() - 1); Timestamp newestLabelTimestamp = getNewestLabelCreationTimestamp(repos); if ((newestLabelTimestamp == null) || noExistingStat || (newestLabelTimestamp.compareTo( Timestamp.valueOf( indexStats.getAnalyzeTime())) < 0)) { indexStats.setPageCount(pageCount); indexStats.setAnalyzeTime(currTimestamp); } else { indexStats = repos.newFemIndexStatistics(); indexStats.setLocalIndex(index); indexStats.setPageCount(pageCount); indexStats.setAnalyzeTime(currTimestamp); } // Set the latest stats in the index record. index.setAnalyzeTime(currTimestamp); index.setPageCount(pageCount); } /** * Retrieves the histogram for a column based on a label setting. * * @param column the column * @param labelTimestamp the creation timestamp of the label setting; null * if there is no label setting * * @return the corresponding histogram, if it exists */ public static FemColumnHistogram getHistogram( FemAbstractColumn column, Timestamp labelTimestamp) { List histogramList = column.getHistogram(); int listSize = histogramList.size(); // If there's no label setting, just return the latest histogram if ((labelTimestamp == null) && (listSize > 0)) { return histogramList.get(listSize - 1); } // Work backwards through the list until we find the first // histogram older than the label timestamp passed in. for (int i = listSize - 1; i >= 0; i--) { FemColumnHistogram histogram = histogramList.get(i); Timestamp statTime = Timestamp.valueOf(histogram.getAnalyzeTime()); if (statTime.compareTo(labelTimestamp) < 0) { return histogram; } } // All histograms were created after the label timestamp passed in, // which means this column had no histograms at the time of the label // setting. return null; } public static void updateHistogram( FarragoRepos repos, FemAbstractColumn column, Long distinctValues, boolean distinctValuesEstimated, float samplePercent, long sampleSize, int barCount, long rowsPerBar, long rowsLastBar, List bars) { FemColumnHistogram histogram = getHistogramForUpdate(repos, column, true); histogram.setAnalyzeTime(createTimestamp()); histogram.setDistinctValueCount(distinctValues); histogram.setDistinctValueCountEstimated(distinctValuesEstimated); histogram.setPercentageSampled(samplePercent); histogram.setSampleSize(sampleSize); histogram.setBarCount(barCount); // TODO: make row count an attribute of bars histogram.setRowsPerBar(rowsPerBar); histogram.setRowsLastBar(rowsLastBar); // only delete the original bars that are in excess of the // new number of bars since we're reusing the original bars List oldBars = histogram.getBar(); int oldBarsCount = oldBars.size(); if (oldBarsCount > barCount) { Iterator iter = oldBars.listIterator(barCount); while (iter.hasNext()) { FemColumnHistogramBar bar = iter.next(); iter.remove(); bar.refDelete(); } } // only update the bars corresponding to new bars; reused bars are // already associated with the histogram if (barCount > oldBarsCount) { int ordinal = oldBarsCount; Iterator iter = bars.listIterator(ordinal); while (iter.hasNext()) { FemColumnHistogramBar bar = iter.next(); bar.setHistogram(histogram); bar.setOrdinal(ordinal++); } } } /** * Determines which histogram record should be updated. Either the latest * one is reused, or a new one is created, if desired. * * @param repos repository * @param column the column for which the histogram will be created * @param createNewHistogram if true and the latest record cannot be * updated, then create a new histogram record * * @return the histogram record to be updated or null if an existing record * cannot be updated and a new one was not created */ public static FemColumnHistogram getHistogramForUpdate( FarragoRepos repos, FemAbstractColumn column, boolean createNewHistogram) { FemColumnHistogram histogram; List histogramList = column.getHistogram(); // If there are no histogram records yet, create one. Otherwise, // determine whether the newest histogram was created before or // after the newest label. If it was created before, then create a // new record; otherwise, reuse the newest one. if (histogramList.isEmpty()) { if (createNewHistogram) { histogram = repos.newFemColumnHistogram(); histogram.setColumn(column); } else { histogram = null; } } else { histogram = histogramList.get(histogramList.size() - 1); Timestamp newestLabelTimestamp = getNewestLabelCreationTimestamp(repos); if ((newestLabelTimestamp != null) && (newestLabelTimestamp.compareTo( Timestamp.valueOf(histogram.getAnalyzeTime())) > 0)) { if (createNewHistogram) { histogram = repos.newFemColumnHistogram(); histogram.setColumn(column); } else { histogram = null; } } } return histogram; } /** * Updates system-maintained attributes of an object. * * @param annotatedElement object to update * @param timestamp timestamp to use for creation/modification * @param isNew whether object is being created */ public static void updateAnnotatedElement( FemAnnotatedElement annotatedElement, String timestamp, boolean isNew) { annotatedElement.setModificationTimestamp(timestamp); if (isNew) { annotatedElement.setCreationTimestamp(timestamp); annotatedElement.setLineageId(UUID.randomUUID().toString()); } } /** * Creates a timestamp reflecting the current time * * @return the timestamp encoded as a string */ public static String createTimestamp() { return new Timestamp(System.currentTimeMillis()).toString(); } /** * Creates a new recovery reference for a recoverable action on an object. * * @param repos repository in which object is defined * @param recoveryType description of recoverable action * @param modelElement object on which recovery would be needed */ public static FemRecoveryReference createRecoveryReference( FarragoRepos repos, RecoveryType recoveryType, CwmModelElement modelElement) { FemRecoveryReference ref = repos.newFemRecoveryReference(); ref.setRecoveryType(recoveryType); CwmDependency dep = repos.newCwmDependency(); dep.setName(recoveryType.toString() + " " + modelElement.getName()); dep.setNamespace(ref); dep.setKind("Recovery"); dep.getClient().add(ref); dep.getSupplier().add(modelElement); // These are typically created outside of DdlValidator, // so fill in standard ModelElement attributes. ref.setVisibility(VisibilityKindEnum.VK_PUBLIC); dep.setVisibility(VisibilityKindEnum.VK_PUBLIC); JmiObjUtil.setMandatoryPrimitiveDefaults(ref); JmiObjUtil.setMandatoryPrimitiveDefaults(dep); return ref; } /** * Resets the row counts for a table * * @param table a column set table * * @deprecated */ public static void resetRowCounts(FemAbstractColumnSet table) { long zero = 0; table.setRowCount(zero); table.setDeletedRowCount(zero); } /** * Resets the row counts for a table, creating new row count stat records, * as needed. * * @param table a column set table * @param repos repository */ public static void resetRowCounts( FemAbstractColumnSet table, FarragoRepos repos) { updateRowCounts(table, 0, 0, repos); } /** * Sets various row counts for an abstract column set. The counts are * reflected both in the abstract column set record as well as the row count * statistics record. * * @param table the abstract column set * @param rowCountStats the row count statistics * @param rowCounts the row counts to be set */ private static void setNewRowCounts( FemAbstractColumnSet table, FemRowCountStatistics rowCountStats, List rowCounts) { String currTimestamp = createTimestamp(); boolean rowCountSet = false; boolean analyzeCountSet = false; for (RowCountStat rowCount : rowCounts) { if (rowCount.type == RowCountStatType.ROW_COUNT) { table.setRowCount(rowCount.count); rowCountStats.setRowCount(rowCount.count); rowCountSet = true; } else if (rowCount.type == RowCountStatType.DELETED_ROW_COUNT) { table.setDeletedRowCount(rowCount.count); rowCountStats.setDeletedRowCount(rowCount.count); } else { assert (rowCount.type == RowCountStatType.ANALYZE_ROW_COUNT); table.setLastAnalyzeRowCount(rowCount.count); table.setAnalyzeTime(currTimestamp); rowCountStats.setAnalyzeTimestamp(currTimestamp); rowCountStats.setAnalyzeRowCount(rowCount.count); analyzeCountSet = true; } } // If only the row count was set and not the analyze count, then // this is a dml update, so update the dml timestamp. if (rowCountSet && !analyzeCountSet) { rowCountStats.setDmlTimestamp(currTimestamp); } } /** * Retrieves the creation timestamp of the most recently created label * stored in the catalog. * * @param repos repository * * @return creation timestamp of the newest label */ public static Timestamp getNewestLabelCreationTimestamp(FarragoRepos repos) { Collection labels = repos.allOfType(FemLabel.class); Timestamp newestTimestamp = null; for (FemLabel label : labels) { Timestamp timestamp = Timestamp.valueOf(label.getCreationTimestamp()); if ((newestTimestamp == null) || (timestamp.compareTo(newestTimestamp) > 0)) { newestTimestamp = timestamp; } } return newestTimestamp; } /** * Retrieves the csn of the oldest label stored in the catalog. * * @param repos repository * * @return csn of the oldest label; null if there are no labels */ public static Long getOldestLabelCsn(FarragoRepos repos) { Collection labels = repos.allOfType(FemLabel.class); Long oldestCsn = null; for (FemLabel label : labels) { // Ignore label aliases if (label.getParentLabel() != null) { continue; } long csn = label.getCommitSequenceNumber(); if ((oldestCsn == null) || (csn < oldestCsn)) { oldestCsn = csn; } } return oldestCsn; } /** * Retrieves the creation timestamp of the labels that bound a specified * label. * * @param referenceLabel the label that will be used to determine the * boundaries * @param repos repository * * @return returns the lower and upper bound timestamps; if the specified * label is the oldest, then the lowerBound is set to null; if the specified * label is the newest, then the upperBound is set to null; therefore, if * the specified label is the only label, then both bounds are set to null */ private static List getLabelBounds( FemLabel referenceLabel, FarragoRepos repos) { Collection labels = repos.allOfType(FemLabel.class); Timestamp lowerBound = null; Timestamp upperBound = null; Timestamp referenceTimestamp = Timestamp.valueOf(referenceLabel.getCreationTimestamp()); for (FemLabel label : labels) { // Ignore label aliases since they are "pointers" to base // labels. So, only the timestamps of base labels are // meaningful in determining which label is the oldest. if (label.getParentLabel() != null) { continue; } String timestamp = label.getCreationTimestamp(); // Ignore new labels that haven't been created yet if (timestamp == null) { continue; } Timestamp labelTimestamp = Timestamp.valueOf(timestamp); int rc = referenceTimestamp.compareTo(labelTimestamp); // Find the newest label older than the reference label if ((rc > 0) && ((lowerBound == null) || (labelTimestamp.compareTo(lowerBound) > 0))) { lowerBound = labelTimestamp; // Find the oldest label newer than the reference label } else if ( (rc < 0) && ((upperBound == null) || (labelTimestamp.compareTo(upperBound) < 0))) { upperBound = labelTimestamp; } } List ret = new ArrayList(); ret.add(lowerBound); ret.add(upperBound); return ret; } /* * Removes from the various catalog tables containing data statistics the * set of stats associated with a label. * * @param label the label * @param repos repository * @param usePreviewRefDelete whether to use the repository's preview * refDelete feature or simply delete the objects */ public static void removeObsoleteStatistics( FemLabel label, FarragoRepos repos, boolean usePreviewRefDelete) { // Locate the stats associated with the label by determining the // timestamps of the two labels that bound the specified label. // Stats that fall within the timestamp range are candidates for // removal. List bounds = FarragoCatalogUtil.getLabelBounds(label, repos); Timestamp lowerBound = bounds.get(0); Timestamp upperBound = bounds.get(1); boolean onlyLabel = false; // If there are no bounds on both ends, then this is the only // label. In that case, the candidates for removal are all stats // older the label. So, set the upper bound to the label's // timestamp. if ((lowerBound == null) && (upperBound == null)) { upperBound = Timestamp.valueOf(label.getCreationTimestamp()); onlyLabel = true; } try { // Start with RowCountStatistics removeObsoleteStatisticsFromTable( repos, repos.allOfType(FemAbstractColumnSet.class), FemAbstractColumnSet.class.getMethod("getRowCountStats"), null, lowerBound, upperBound, onlyLabel, usePreviewRefDelete); // Move on to ColumnHistogram removeObsoleteStatisticsFromTable( repos, repos.allOfType(FemAbstractColumn.class), FemAbstractColumn.class.getMethod("getHistogram"), FemColumnHistogram.class.getMethod("getAnalyzeTime"), lowerBound, upperBound, onlyLabel, usePreviewRefDelete); // Finally, IndexStatistics removeObsoleteStatisticsFromTable( repos, repos.allOfType(FemLocalIndex.class), FemLocalIndex.class.getMethod("getIndexStats"), FemIndexStatistics.class.getMethod("getAnalyzeTime"), lowerBound, upperBound, onlyLabel, usePreviewRefDelete); } catch (Exception e) { throw Util.newInternal(e); } } /** * Removes statistics in between 2 timestamp boundaries, provided the stat * is not the only remaining statistic record within the timestamp range. * The candidate stats are located by walking through a list of parent * objects that reference stats. * * @param the type of the object that references the stat * records * @param repos repository * @param parentList list of parent objects * @param statsGetter method that retrieves the list of stat records from * each parent object * @param timestampGetter method that retrieves the timestamp from each * stats record; null if this is a RowCountStatistics object; row count * stats are handled as a special case * @param lowerBound the lower bound timestamp boundary * @param upperBound the upper bound timestamp boundary * @param onlyLabel true if this is the special case where the label being * dropped is the only remaining one; in this case, the lowerBound should be * null * @param usePreviewRefDelete whether to use the repository's preview * refDelete feature or just delete the objects */ private static void removeObsoleteStatisticsFromTable( FarragoRepos repos, Collection parentList, Method statsGetter, Method timestampGetter, Timestamp lowerBound, Timestamp upperBound, boolean onlyLabel, boolean usePreviewRefDelete) throws Exception { EnkiMDRepository mdrRepos = repos.getEnkiMdrRepos(); for (ParentType parent : parentList) { // We make a copy of the actual list to avoid modifying the // repository when this method is used as part of previewRefDelete List statsList = new ArrayList( (List) statsGetter.invoke(parent)); // Determine the indices of the stats that are within the bounds int lowerIdx = -1; int upperIdx = -1; int i = 0; Iterator iter = statsList.iterator(); while (iter.hasNext()) { RefObject stats = (RefObject) iter.next(); Timestamp statsTimestamp; if (timestampGetter != null) { statsTimestamp = Timestamp.valueOf( (String) timestampGetter.invoke( stats)); } else { assert (stats instanceof FemRowCountStatistics); statsTimestamp = getMaxTimestamp( (FemAbstractColumnSet) parent, (FemRowCountStatistics) stats); } if (!timestampInRange(lowerBound, upperBound, statsTimestamp)) { // Stats are ordered so if we're out of range and have // already found an entry matching the lower bound, // then we've exceeded the upper bound. if (lowerIdx >= 0) { break; } } else { if (lowerIdx < 0) { lowerIdx = i; upperIdx = i; } else { upperIdx++; } } i++; } // We can only remove stats within the range if there 2 of them, // since we can't remove the newest one in the range. Note that // because stats are removed as labels are dropped/replaced, // and there should never be more than one set of stats associated // with each label, the located range should never consist of more // than 2 sets of stats. if (lowerIdx >= 0) { assert ((upperIdx - lowerIdx) <= 1); if (onlyLabel) { assert (lowerBound == null); if (statsList.size() >= 2) { // For the special case where we're dropping the only // label, there is a stat associated with that // label that can be dropped, and there is at least // one other stat outside the range, then we should // still be able to drop the one stat that's // in the range. However, based on the value of // upperIdx, we don't meet the criteria of having 2 // stats within the range. So, bump up upperIdx so we // can force the one stat to be dropped. assert (lowerIdx == upperIdx); upperIdx++; } } if ((upperIdx - lowerIdx) > 0) { ListIterator listIter = statsList.listIterator(lowerIdx); i = lowerIdx; // Remove all but the newest stat in the range while ((i < upperIdx) && listIter.hasNext()) { RefObject stats = listIter.next(); listIter.remove(); if (usePreviewRefDelete) { mdrRepos.previewRefDelete(stats); } else { stats.refDelete(); } i++; } } } } } /** * Determines if a specified timestamp is within 2 bounds. The bounds are * non-inclusive. * * @param lowerBound the lower bound; if null, then there is no lower bound * @param upperBound the upper bound; if null, then there is no upper bound * @param timestamp the timestamp; if null, the timestamp represents a very * old timestamp and therefore only qualifies if there is no explicit lower * bound * * @return true if the timestamp is within bounds */ private static boolean timestampInRange( Timestamp lowerBound, Timestamp upperBound, Timestamp timestamp) { if (timestamp == null) { if (lowerBound == null) { return true; } else { return false; } } if ((lowerBound == null) || (timestamp.compareTo(lowerBound) > 0)) { if ((upperBound == null) || (timestamp.compareTo(upperBound) < 0)) { return true; } } return false; } /** * Retrieves current backup data stored in the catalog. Information on the * full backup, if it exists, is always returned first, followed by * information on the last backup. * * @param repos repository * * @return list containing current backup data */ public static List getCurrentBackupData(FarragoRepos repos) { List retList = new ArrayList(); Collection backups = repos.allOfType(FemSystemBackup.class); assert ((backups.size() == 0) || (backups.size() == 2)); for (FemSystemBackup backup : backups) { assert (backup.getStatus() == BackupStatusTypeEnum.COMPLETED); BackupData backupData = new BackupData( backup.getType(), backup.getCommitSequenceNumber(), backup.getStartTimestamp()); if (backup.getType() == BackupTypeEnum.FULL) { retList.add(0, backupData); } else { retList.add(backupData); } } return retList; } /** * Adds new records to the system backup catalog corresponding to a pending * backup. * * @param repos repository * @param type type of backup * @param csn commit sequence number corresponding to the backup * @param startTime start time of the backup */ public static void addPendingSystemBackup( FarragoRepos repos, String type, Long csn, String startTime) { for (int i = 0; i < 2; i++) { FemSystemBackup backup = repos.newFemSystemBackup(); if (i == 0) { backup.setType(BackupTypeEnum.LAST); } else { backup.setType(BackupTypeEnum.FULL); } backup.setCommitSequenceNumber(csn); backup.setStartTimestamp(startTime); backup.setStatus(BackupStatusTypeEnum.PENDING); if (!type.equals("FULL")) { break; } } } /** * Updates the system backup catalog data depending on whether the last * pending backup (if any) succeeded or failed. However, if the data * indicates that a partial restore has been done, then nothing is updated. * * @param repos repository * @param backupSucceeded true if the last backup succeeded * @param setEndTimestamp if true, record the current timestamp as the * ending timestamp when updating pending data to completed * * @return true if a partial restore was done */ public static boolean updatePendingBackupData( FarragoRepos repos, boolean backupSucceeded, boolean setEndTimestamp) { Collection backups = repos.allOfType(FemSystemBackup.class); // First see which pending records exist and whether a partial restore // was done. boolean pendingFull = false; boolean pendingLast = false; for (FemSystemBackup backup : backups) { if (backup.getStatus() == BackupStatusTypeEnum.COMPLETED && backup.getStartTimestamp() == null) { return true; } if (backup.getStatus() == BackupStatusTypeEnum.PENDING) { if (backup.getType() == BackupTypeEnum.LAST) { pendingLast = true; } else { assert (backup.getType() == BackupTypeEnum.FULL); pendingFull = true; } } } // If no pending records, there's no work to do if (!pendingFull && !pendingLast) { return false; } if (pendingFull) { assert (pendingLast); } // If the last backup succeeded, delete the completed records // corresponding to the pending records, then update the pending // records to completed. Otherwise, just delete the pending records. if (backupSucceeded) { for (FemSystemBackup backup : backups) { if ((backup.getStatus() == BackupStatusTypeEnum.COMPLETED) && ((pendingFull && (backup.getType() == BackupTypeEnum.FULL)) || (pendingLast && (backup.getType() == BackupTypeEnum.LAST)))) { backup.refDelete(); } } } backups = repos.allOfType(FemSystemBackup.class); for (FemSystemBackup backup : backups) { if (backup.getStatus() == BackupStatusTypeEnum.PENDING) { if (backupSucceeded) { backup.setStatus(BackupStatusTypeEnum.COMPLETED); if (setEndTimestamp) { backup.setEndTimestamp(createTimestamp().toString()); } } else { backup.refDelete(); } } } return false; } /** * Adds or updates records in the system backup catalog, indicating that a * partial restore has been completed. * * @param repos repository */ public static void addPendingRestore(FarragoRepos repos) { Collection backups = repos.allOfType(FemSystemBackup.class); // See if there already are backup records. If there are, null // out the starting timestamp. That's the indicator that only a // partial restore has been completed. int updateCount = 0; for (FemSystemBackup backup : backups) { assert (backup.getStatus() == BackupStatusTypeEnum.COMPLETED); backup.setStartTimestamp(null); backup.setEndTimestamp(null); updateCount++; } assert (updateCount == 0 || updateCount == 2); if (updateCount > 0) { return; } // If not, add new records. addNewPendingRestoreRecord(repos, BackupTypeEnum.LAST); addNewPendingRestoreRecord(repos, BackupTypeEnum.FULL); } private static void addNewPendingRestoreRecord( FarragoRepos repos, BackupTypeEnum type) { FemSystemBackup backup = repos.newFemSystemBackup(); backup.setStartTimestamp(null); backup.setEndTimestamp(null); backup.setType(type); backup.setStatus(BackupStatusTypeEnum.COMPLETED); } //~ Inner Classes ---------------------------------------------------------- /** * Helper class used to represent a specific type of row count statistic */ private static class RowCountStat { RowCountStatType type; long count; RowCountStat(RowCountStatType type, long count) { this.type = type; this.count = count; } } /** * Helper class used to represent backup information stored in the backup * catalog. */ public static class BackupData { public BackupType type; public long csn; public String startTimestamp; BackupData(BackupType type, long csn, String startTimestamp) { this.type = type; this.csn = csn; this.startTimestamp = startTimestamp; } } } // End FarragoCatalogUtil.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoTransientStorageFactory.java0000444000175000017500000000471211173714170030772 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoTransientStorageFactory.java#12 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.util.*; import org.netbeans.mdr.persistence.*; import org.netbeans.mdr.persistence.memoryimpl.*; /** * Factory for {@link FarragoTransientStorage}. Adapted from * org.netbeans.mdr.persistence.memoryimpl. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoTransientStorageFactory.java#12 $ */ public class FarragoTransientStorageFactory implements StorageFactory { //~ Static fields/initializers --------------------------------------------- // distinguish this from normal memory storage static final String NULL_STORAGE_ID = "#"; private static final MOFID NULL_MOFID = new MOFID(0, NULL_STORAGE_ID); private static FarragoTransientStorage singletonStorage; //~ Constructors ----------------------------------------------------------- public FarragoTransientStorageFactory() { } //~ Methods ---------------------------------------------------------------- // implement StorageFactory public synchronized Storage createStorage(Map properties) throws StorageException { singletonStorage = new FarragoTransientStorage(); return singletonStorage; } // implement StorageFactory public MOFID createNullMOFID() throws StorageException { return NULL_MOFID; } } // End FarragoTransientStorageFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoTransientStorage.java0000444000175000017500000002450611173714170027445 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoTransientStorage.java#12 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.io.*; import java.util.*; import org.netbeans.mdr.persistence.*; import org.netbeans.mdr.persistence.memoryimpl.*; import org.netbeans.mdr.util.*; /** * FarragoTransientStorage provides storage for transient MDR objects. Adapted * from org.netbeans.mdr.persistence.memoryimpl. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoTransientStorage.java#12 $ */ class FarragoTransientStorage extends StorageImpl { //~ Static fields/initializers --------------------------------------------- // NOTE jvs 6-May-2004: Another hack. This is what actually implements the // desired transient effect: when true, commits are converted into // rollbacks. This isn't set until after all storage initialization is // completed, so system-defined data stays around permanently. Need to make // this work properly for the system/user catalog split. static boolean ignoreCommit; //~ Instance fields -------------------------------------------------------- // NOTE jvs 6-May-2004: I had to extend StorageImpl to avoid having to // copy the entire index classes. Watch out for the fact that // the data members here shadow the unused ones in the superclass! private final HashMap maps = new HashMap(); private PVIndex primaryIndex; private Set newIndexes = new HashSet(); private HashMap removedIndexes = new HashMap(); //~ Constructors ----------------------------------------------------------- FarragoTransientStorage() { super(FarragoTransientStorageFactory.NULL_STORAGE_ID, null); ignoreCommit = false; } //~ Methods ---------------------------------------------------------------- // implement Storage public synchronized void create( boolean replace, ObjectResolver resolver) throws StorageException { createPrimaryIndex(); } // implement Storage public synchronized void close() throws StorageException { shutDown(); } // implement Storage public synchronized boolean delete() throws StorageException { return false; } // implement Storage public synchronized boolean exists() throws StorageException { return false; } // implement Storage public synchronized void open( boolean createOnNoExist, ObjectResolver resolver) throws StorageException { createPrimaryIndex(); } // implement Storage public synchronized void objectStateWillChange(Object key) throws StorageException { primaryIndex.willChange(key); } // implement Storage public synchronized void objectStateChanged(Object key) throws StorageException { primaryIndex.changed(key); } // implement Storage public synchronized void rollBackChanges() throws StorageException { // drop all indexes created during the transaction Iterator iter = newIndexes.iterator(); while (iter.hasNext()) { maps.remove(iter.next()); } // restore all indexes existing before the transaction that have been // removed by the transaction iter = removedIndexes.keySet().iterator(); while (iter.hasNext()) { String name = (String) iter.next(); maps.put( name, removedIndexes.get(name)); } // call rollback on all indexes iter = maps.entrySet().iterator(); while (iter.hasNext()) { TxnIndex index = (TxnIndex) ((Map.Entry) iter.next()).getValue(); index.rollBackChangesPublic(); } if (primaryIndex != null) { primaryIndex.rollBackChangesPublic(); } } // implement Storage public synchronized void shutDown() throws StorageException { commitChanges(); } // implement Storage public synchronized void commitChanges() throws StorageException { if (ignoreCommit) { rollBackChanges(); return; } newIndexes.clear(); removedIndexes.clear(); // call commit on all indexes Iterator iter = maps.entrySet().iterator(); while (iter.hasNext()) { TxnIndex index = (TxnIndex) ((Map.Entry) iter.next()).getValue(); index.commitChangesPublic(); } if (primaryIndex != null) { primaryIndex.commitChangesPublic(); } } // implement Storage public synchronized SinglevaluedIndex getSinglevaluedIndex(String name) throws StorageException { return (SinglevaluedIndex) getIndex(name); } // implement Storage public synchronized MultivaluedIndex getMultivaluedIndex(String name) throws StorageException { return (MultivaluedIndex) getIndex(name); } // implement Storage public synchronized MultivaluedOrderedIndex getMultivaluedOrderedIndex( String name) throws StorageException { return (MultivaluedOrderedIndex) getIndex(name); } // implement Storage public synchronized void dropIndex(String name) throws StorageException { Object index = maps.remove(name); if ((index != null) && !newIndexes.remove(name)) { removedIndexes.put(name, index); } } private synchronized void addIndex( String name, Index index) throws StorageException { maps.put(name, index); newIndexes.add(name); } // implement Storage public synchronized SinglevaluedIndex createSinglevaluedIndex( String name, EntryType keyType, EntryType valueType) throws StorageException { assert (!valueType.equals(EntryType.STREAMABLE)); SinglevaluedIndex sm = new SVIndex(name, this, keyType, valueType); addIndex(name, sm); return sm; } // implement Storage public synchronized MultivaluedOrderedIndex createMultivaluedOrderedIndex( String name, EntryType keyType, EntryType valueType, boolean unique) throws StorageException { MultivaluedOrderedIndex sm = new MVIndex(name, this, keyType, valueType, unique); addIndex(name, sm); return sm; } // implement Storage public synchronized MultivaluedIndex createMultivaluedIndex( String name, EntryType keyType, EntryType valueType, boolean unique) throws StorageException { MultivaluedIndex sm = new MVIndex(name, this, keyType, valueType, unique); addIndex(name, sm); return sm; } // implement Storage public synchronized SinglevaluedIndex getPrimaryIndex() throws StorageException { return primaryIndex; } // implement Storage private void createPrimaryIndex() throws StorageException { primaryIndex = new PVIndex(this); } // implement Storage public synchronized Index getIndex(String name) throws StorageException { return (Index) maps.get(name); } //~ Inner Interfaces ------------------------------------------------------- private static interface TxnIndex { public void commitChangesPublic() throws StorageException; public void rollBackChangesPublic() throws StorageException; } //~ Inner Classes ---------------------------------------------------------- private static class PVIndex extends PrimaryIndexImpl implements TxnIndex { PVIndex(StorageImpl storage) { super(storage); } public void commitChangesPublic() throws StorageException { commitChanges(); } public void rollBackChangesPublic() throws StorageException { rollBackChanges(); } } private static class SVIndex extends SinglevaluedIndexImpl implements TxnIndex { SVIndex( String name, StorageImpl storage, Storage.EntryType keyType, Storage.EntryType valueType) { super(name, storage, keyType, valueType); } public void commitChangesPublic() throws StorageException { commitChanges(); } public void rollBackChangesPublic() throws StorageException { rollBackChanges(); } } private static class MVIndex extends MultivaluedOrderedIndexImpl implements TxnIndex { public MVIndex( String name, StorageImpl storage, Storage.EntryType keyType, Storage.EntryType valueType, boolean unique) { super(name, storage, keyType, valueType, unique); } public void commitChangesPublic() throws StorageException { commitChanges(); } public void rollBackChangesPublic() throws StorageException { rollBackChanges(); } } } // End FarragoTransientStorage.java eigenbase-farrago-0.9.0/src/net/sf/farrago/catalog/FarragoReposUtil.java0000444000175000017500000010126411173714170026074 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposUtil.java#21 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.catalog; import java.io.*; import java.net.*; import java.nio.charset.*; import java.util.*; import javax.jmi.model.*; import javax.jmi.reflect.*; import javax.jmi.xmi.*; import net.sf.farrago.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.eigenbase.util.*; import org.netbeans.api.mdr.*; import org.netbeans.api.xmi.*; /** * Static utilities for manipulating the Farrago repository. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/catalog/FarragoReposUtil.java#21 $ */ public abstract class FarragoReposUtil { //~ Static fields/initializers --------------------------------------------- public static final String FARRAGO_CATALOG_EXTENT = "FarragoCatalog"; public static final String FARRAGO_METAMODEL_EXTENT = "FarragoMetamodel"; public static final String FARRAGO_PACKAGE_NAME = "Farrago"; //~ Methods ---------------------------------------------------------------- /** * Exports a submodel, generating qualified references by name to objects * outside of the submodel. * * @param mdrRepos MDR repository containing submodel to export * @param outputFile file into which XMI should be written * @param subPackageName name of package containing submodel to be exported */ public static void exportSubModel( MDRepository mdrRepos, File outputFile, String subPackageName) throws Exception { XMIWriter xmiWriter = XMIWriterFactory.getDefault().createXMIWriter(); ExportRefProvider refProvider = new ExportRefProvider( subPackageName); xmiWriter.getConfiguration().setReferenceProvider(refProvider); FileOutputStream outStream = new FileOutputStream(outputFile); try { xmiWriter.write( outStream, "SUBMODEL", mdrRepos.getExtent(FARRAGO_METAMODEL_EXTENT), "1.2"); if (!refProvider.subPackageFound) { throw new NoSuchElementException(subPackageName); } } finally { outStream.close(); } } public static void importSubModel( MDRepository mdrRepos, URL inputUrl) throws Exception { if (((EnkiMDRepository) mdrRepos).isExtentBuiltIn( FARRAGO_METAMODEL_EXTENT)) { return; } XMIReader xmiReader = XMIReaderFactory.getDefault().createXMIReader(); ImportRefResolver refResolver = new ImportRefResolver( (Namespace) mdrRepos.getExtent(FARRAGO_CATALOG_EXTENT) .refMetaObject()); xmiReader.getConfiguration().setReferenceResolver(refResolver); boolean rollback = false; try { mdrRepos.beginTrans(true); rollback = true; InvalidXmlCharFilterInputStream filter = new InvalidXmlCharFilterInputStream(inputUrl.openStream()); xmiReader.read( filter, inputUrl.toString(), mdrRepos.getExtent(FARRAGO_METAMODEL_EXTENT)); if (filter.getNumInvalidCharsFiltered() > 0) { FarragoTrace.getReposTracer().warning( "Filtered " + filter.getNumInvalidCharsFiltered() + " invalid characters from XMI at '" + inputUrl.toString() + "'"); } rollback = false; mdrRepos.endTrans(); } finally { if (rollback) { mdrRepos.endTrans(true); } } } public static void dumpRepository() throws Exception { dumpRepository(new FarragoModelLoader()); } public static void dumpRepository( FarragoModelLoader modelLoader) throws Exception { dumpRepository(modelLoader, false); } public static void dumpRepository( FarragoModelLoader modelLoader, boolean metamodelDumpOnly) throws Exception { FarragoProperties farragoProps = modelLoader.getFarragoProperties(); File catalogDir = farragoProps.getCatalogDir(); File metamodelDump = new File(catalogDir, "FarragoMetamodelDump.xmi"); File catalogDump = new File(catalogDir, "FarragoCatalogDump.xmi"); boolean success = false; try { FarragoPackage farragoPackage = modelLoader.loadModel(FARRAGO_CATALOG_EXTENT, false); modelLoader.getMdrRepos().beginTrans(false); try { exportExtent( modelLoader.getMdrRepos(), metamodelDump, FARRAGO_METAMODEL_EXTENT); if (!metamodelDumpOnly) { exportExtent( modelLoader.getMdrRepos(), catalogDump, FARRAGO_CATALOG_EXTENT); } } finally { modelLoader.getMdrRepos().endTrans(); } deleteStorage(modelLoader, farragoPackage); success = true; } finally { // Close session started in modelLoader.loadModel modelLoader.close(); if (!success) { metamodelDump.delete(); catalogDump.delete(); } } } /** * @deprecated pass FarragoModelLoader parameter */ public static boolean isReloadNeeded() { return isReloadNeeded(new FarragoModelLoader()); } public static boolean isReloadNeeded(FarragoModelLoader modelLoader) { File catalogDir = modelLoader.getFarragoProperties().getCatalogDir(); return new File(catalogDir, "FarragoMetamodelDump.xmi").exists(); } /** * @deprecated pass FarragoModelLoader parameter */ public static void reloadRepository() throws Exception { reloadRepository(new FarragoModelLoader()); } public static void reloadRepository( FarragoModelLoader modelLoader) throws Exception { File catalogDir = modelLoader.getFarragoProperties().getCatalogDir(); File metamodelDump = new File(catalogDir, "FarragoMetamodelDump.xmi"); String catalogDumpName = "FarragoCatalogDump.xmi"; File catalogDump = new File(catalogDir, catalogDumpName); try { modelLoader.initStorage(false); // import metamodel importExtent( modelLoader.getMdrRepos(), metamodelDump, FARRAGO_METAMODEL_EXTENT, null, null); // import catalog importExtent( modelLoader.getMdrRepos(), catalogDump, FARRAGO_CATALOG_EXTENT, FARRAGO_METAMODEL_EXTENT, FARRAGO_PACKAGE_NAME); metamodelDump.delete(); catalogDump.delete(); } finally { modelLoader.close(); } } public static void exportExtent( MDRepository mdrRepos, File file, String extentName) throws Exception { RefPackage refPackage = mdrRepos.getExtent(extentName); XmiWriter xmiWriter = XMIWriterFactory.getDefault().createXMIWriter(); OutputStream outStream = new FileOutputStream(file); try { xmiWriter.write(outStream, refPackage, "1.2"); } finally { outStream.close(); } } private static void deleteStorage( FarragoModelLoader modelLoader, FarragoPackage farragoPackage) throws Exception { EnkiMDRepository repos = (EnkiMDRepository) modelLoader.getMdrRepos(); repos.dropExtentStorage(farragoPackage); } private static void importExtent( MDRepository mdrRepos, File file, String extentName, String metaPackageExtentName, String metaPackageName) throws Exception { mdrRepos.beginTrans(true); boolean rollback = true; try { RefPackage extent; if (metaPackageExtentName != null) { ModelPackage modelPackage = (ModelPackage) mdrRepos.getExtent(metaPackageExtentName); MofPackage metaPackage = null; for (Object o : modelPackage.getMofPackage().refAllOfClass()) { MofPackage result = (MofPackage) o; if (result.getName().equals(metaPackageName)) { metaPackage = result; break; } } extent = mdrRepos.createExtent(extentName, metaPackage); } else { if (((EnkiMDRepository) mdrRepos).isExtentBuiltIn(extentName)) { // Go ahead and rollback; we haven't changed anything. return; } extent = mdrRepos.createExtent(extentName); } XmiReader xmiReader = XMIReaderFactory.getDefault().createXMIReader(); InputStream in = new FileInputStream(file); InvalidXmlCharFilterInputStream filter = new InvalidXmlCharFilterInputStream(in); xmiReader.read( filter, file.toURL().toString(), extent); if (filter.getNumInvalidCharsFiltered() > 0) { FarragoTrace.getReposTracer().warning( "Filtered " + filter.getNumInvalidCharsFiltered() + " invalid characters from XMI file '" + file.getAbsolutePath() + "'"); } rollback = false; } finally { mdrRepos.endTrans(rollback); } } private static void mainExportSubModel(String [] args) throws Exception { assert (args.length == 3); File file = new File(args[1]); String subPackageName = args[2]; FarragoModelLoader modelLoader = new FarragoModelLoader(); try { modelLoader.loadModel(FARRAGO_CATALOG_EXTENT, false); exportSubModel( modelLoader.getMdrRepos(), file, subPackageName); } finally { modelLoader.close(); } } private static void mainImportSubModel(String [] args) throws Exception { assert (args.length == 2); File file = new File(args[1]); FarragoModelLoader modelLoader = new FarragoModelLoader(); try { modelLoader.loadModel(FARRAGO_CATALOG_EXTENT, false); importSubModel( modelLoader.getMdrRepos(), file.toURL()); } finally { modelLoader.close(); } } public static void main(String [] args) throws Exception { // TODO: proper arg checking assert (args.length > 0); if (args[0].equals("exportSubModel")) { mainExportSubModel(args); } else if (args[0].equals("importSubModel")) { mainImportSubModel(args); } else { throw new IllegalArgumentException(args[0]); } } //~ Inner Classes ---------------------------------------------------------- private static class ExportRefProvider implements XMIReferenceProvider { private final String subPackageName; boolean subPackageFound; ExportRefProvider( String subPackageName) { this.subPackageName = subPackageName; } // implement XMIReferenceProvider public XMIReferenceProvider.XMIReference getReference(RefObject obj) { RefObject parent = obj; if (obj instanceof Tag) { Collection c = ((Tag) obj).getElements(); if (c.size() == 1) { parent = (RefObject) c.iterator().next(); } } List nameList = new ArrayList(); do { String name = (String) parent.refGetValue("name"); nameList.add(name); if (subPackageName.equals(name)) { subPackageFound = true; return new XMIReferenceProvider.XMIReference( "SUBMODEL", Long.toString(JmiObjUtil.getObjectId(obj))); } parent = (RefObject) parent.refImmediateComposite(); } while (parent != null); Collections.reverse(nameList); int k = 0; StringBuilder sb = new StringBuilder(); for (String name : nameList) { if (k++ > 0) { sb.append('/'); } sb.append(name); } return new XMIReferenceProvider.XMIReference( "REPOS", sb.toString()); } } private static class ImportRefResolver implements XMIReferenceResolver { private final Namespace root; ImportRefResolver(Namespace root) { this.root = root; } // implement XMIReferenceResolver public void register( String systemId, String xmiId, RefObject object) { // don't care } // implement XMIReferenceResolver public void resolve( XMIReferenceResolver.Client client, RefPackage extent, String systemId, XMIInputConfig configuration, Collection hrefs) { Iterator iter = hrefs.iterator(); while (iter.hasNext()) { String href = iter.next().toString(); int nameStart = href.indexOf('#') + 1; assert (nameStart != 0); String [] names = href.substring(nameStart).split("/"); assert (names[0].equals(root.getName())); Namespace ns = root; try { for (int i = 1; i < (names.length - 1); ++i) { ns = (Namespace) ns.lookupElement(names[i]); } ModelElement element; if (names.length == 1) { element = (ModelElement) ns; } else { element = ns.lookupElement(names[names.length - 1]); } client.resolvedReference(href, element); } catch (NameNotFoundException ex) { throw Util.newInternal(ex); } } } } public static class InvalidXmlCharFilterInputStream extends InputStream { // Various common byte order marks (BOMs) to detect -- normally // done by the XML parser, but we need to be able to decode characters // from the stream before they get that far. private static final byte [] UTF16_BE_BOM = toBytes( new int[] { 0xFE, 0xFF, // 0x00, 0x3C, // < 0x00, 0x3F, // ? 0x00, 0x78, // x 0x00, 0x6D, // m 0x00, 0x6C, // l 0x00, 0x20, // }); private static final byte [] UTF16_BE_SANS_BOM = toBytes( new int[] { 0x00, 0x3C, // < 0x00, 0x3F, // ? 0x00, 0x78, // x 0x00, 0x6D, // m 0x00, 0x6C, // l 0x00, 0x20, // }); private static final byte [] UTF16_LE_BOM = toBytes( new int[] { 0xFF, 0xFE, // 0x3C, 0x00, // < 0x3F, 0x00, // ? 0x78, 0x00, // x 0x6D, 0x00, // m 0x6C, 0x00, // l 0x20, 0x00, // }); private static final byte [] UTF16_LE_SANS_BOM = toBytes( new int[] { 0x3C, 0x00, // < 0x3F, 0x00, // ? 0x78, 0x00, // x 0x6D, 0x00, // m 0x6C, 0x00, // l 0x20, 0x00, // }); private static final byte [] UTF8_BOM = toBytes( new int[] { 0xEF, 0xBB, 0xBF, // byte order mark 0x3C, // < 0x3F, // ? 0x78, // x 0x6D, // m 0x6C, // l 0x20, // }); private static final byte [] OTHER_ASCII_LIKE = toBytes( new int[] { 0x3C, // < 0x3F, // ? 0x78, // x 0x6D, // m 0x6C, // l 0x20, // }); private static final Map ALL_DECLS; static { HashMap decls = new HashMap(); decls.put(UTF16_BE_BOM, "UTF-16BE"); decls.put(UTF16_BE_SANS_BOM, "UTF-16BE"); decls.put(UTF16_LE_BOM, "UTF-16LE"); decls.put(UTF16_LE_SANS_BOM, "UTF-16LE"); decls.put(UTF8_BOM, "UTF-8"); decls.put(OTHER_ASCII_LIKE, ""); ALL_DECLS = Collections.unmodifiableMap(decls); } // Choose a reasonable upper limit for the maximum length of an XML // declaration, including encoding name. private static final int MAX_DECL_SIZE = 256; private final InputStream in; private int numInvalidCharsFiltered; private ByteOutputStream outputBuffer; private Writer outputBufferWriter; private Reader reader; private char [] inputBuffer; public InvalidXmlCharFilterInputStream(InputStream in) throws IOException { if (!in.markSupported()) { in = new BufferedInputStream(in); } this.in = in; this.numInvalidCharsFiltered = 0; this.outputBuffer = new ByteOutputStream(4096); Charset charset = guessCharset(in, outputBuffer); // Assume maximum encoding overhead is 2 bytes per char. in.mark(2 * MAX_DECL_SIZE); this.reader = new BufferedReader(new InputStreamReader(in, charset)); Charset encodedCharset = getCharsetFromXmlDecl(reader); if ((encodedCharset != null) && !charset.equals(encodedCharset)) { boolean sameButNoEndianness = false; String encodedName = encodedCharset.name(); String name = charset.name(); if (name.startsWith(encodedName)) { String suffix = name.substring(encodedName.length()); sameButNoEndianness = suffix.equals("LE") || suffix.equals("BE"); } // Ignore the case where we properly detect, say UTF-16 LE, // but the XML decl doesn't specify byte order. The Java // UTF-16 Charset implementation assumes network byte order // (UTF-16 BE) which would cause problems. if (!sameButNoEndianness) { charset = encodedCharset; in.reset(); this.reader = new InputStreamReader(in, charset); } } this.outputBufferWriter = new OutputStreamWriter(outputBuffer, charset); this.inputBuffer = new char[(int) Math.round( charset.newDecoder().averageCharsPerByte() * 4096.0)]; } /** * Converts an int array to byte array. Assumes all int values in the * array contain only 8 bits of data. * * @param data int array * * @return byte array */ private static byte [] toBytes(int [] data) { byte [] bytes = new byte[data.length]; for (int i = 0; i < data.length; i++) { bytes[i] = (byte) (data[i] & 0xFF); } return bytes; } /** * Compares two bytes arrays. If the data array does not begin with * exactly the bytes specified in the expected array, returns false. The * data array may be longer than the expected array, but not shorter. * * @param data data to test * @param expected expected value * * @return true if data and expected match (see above) */ private static boolean matches(byte [] data, byte [] expected) { final int len = expected.length; if (len > data.length) { return false; } for (int i = 0; i < len; i++) { if (data[i] != expected[i]) { return false; } } return true; } /** * Guesses the character set used by the input stream, storing * characters in the buffer stream. The first block of data in the input * stream is compared against the XML declarations in {@link #ALL_DECLS} * to find a characters set suitable for reading at least the XML * declaration from the input stream. * * @param in input stream * @param bufferStream buffer stream for temporary storage * * @return best-guess character set for the input stream * * @throws IOException on I/O error, if the character set cannot be * detected or instantiated */ private static Charset guessCharset( InputStream in, ByteOutputStream bufferStream) throws IOException { in.mark(2 * MAX_DECL_SIZE); int size = 0; while (size < MAX_DECL_SIZE) { int bytesRead = in.read(bufferStream.array(), size, MAX_DECL_SIZE - size); bufferStream.size(bufferStream.size() + bytesRead); if (bytesRead < 0) { break; } size += bytesRead; } bufferStream.reset(); in.reset(); String charsetName = null; for (Map.Entry entry : ALL_DECLS.entrySet()) { if (matches(bufferStream.array(), entry.getKey())) { charsetName = entry.getValue(); break; } } if (charsetName == null) { throw new IOException( "Unsupported XML encoding (or not a valid XML file)"); } else if (charsetName.length() == 0) { charsetName = "ISO-8859-1"; } return Charset.forName(charsetName); } /** * Parses the XML declaration at the start of the Reader's input and * returns the specified encoding, if any. The given Reader must be * configured with a character set encoding capable of reading the XML * declaration (which will only contain a limited set of characters). * * @param reader a Reader configured with a suitable character set * encoding * * @return the character set specified by the XML declaration, or null * if not found * * @throws IOException on I/O error or if the named character set cannot * be instantiated * @throws IndexOutOfBoundsException if the XML declaration is malformed */ private static Charset getCharsetFromXmlDecl(Reader reader) throws IOException { final int max = 1024; reader.mark(max); try { StringBuilder b = new StringBuilder(); int n = 0; while (n < max) { int ch = reader.read(); b.append((char) ch); n++; if ((n > 2) && "?>".equals(b.substring(n - 2, n))) { break; } } int encoding = b.indexOf("encoding"); if (encoding < 0) { return null; } try { encoding += 8; while (Character.isWhitespace(b.charAt(encoding))) { encoding++; } if (b.charAt(encoding) != '=') { return null; } encoding++; while (Character.isWhitespace(b.charAt(encoding))) { encoding++; } char quote = b.charAt(encoding); if ((quote != '\'') && (quote != '"')) { return null; } int encodingEnd = ++encoding; while (b.charAt(encodingEnd) != quote) { encodingEnd++; } String charsetName = b.substring(encoding, encodingEnd); if (charsetName.length() == 0) { return null; } return Charset.forName(charsetName); } catch (IndexOutOfBoundsException e) { return null; } } finally { reader.reset(); } } @Override public boolean markSupported() { return false; } @Override public int available() throws IOException { return outputBuffer.remaining(); } @Override public void close() throws IOException { outputBuffer.reset(); in.close(); } @Override public int read() throws IOException { while (true) { // If there are bytes in the output buffer (e.g. from a // multi-byte encoding), return them. if (outputBuffer.remaining() > 0) { int result = outputBuffer.get(); return result & 0xFF; } // Reset buffer, it's empty. outputBuffer.reset(); // Read the next character from the underlying Reader int ch = reader.read(); if (ch == -1) { return -1; } if (check(ch)) { // Valid XML, encode it into the output buffer and restart // the loop. outputBufferWriter.write(ch); outputBufferWriter.flush(); continue; } // Invalid character FarragoTrace.getMdrTracer().fine( "Invalid XML character: " + Integer.toHexString(ch)); numInvalidCharsFiltered++; } } private boolean check(int ch) { return ((ch >= 0x0020) && (ch <= 0xD7FF)) || ((ch >= 0xE000) && (ch <= 0xFFFD)) || (ch == 0x0009) || (ch == 0x000A) || (ch == 0x000D); } @Override public int read(byte [] b, int off, int len) throws IOException { while (true) { // Enough bytes in the output buffer to satisfy the read // request, so copy them into b and return. if (outputBuffer.remaining() >= len) { outputBuffer.get(b, off, len); return len; } else { // Compact the buffer, it might not be empty. outputBuffer.compact(); // Read a block of characters. int charsRead = reader.read(inputBuffer); if (charsRead < 0) { // Reader is at EOS, if there are no bytes remaining in // the output buffer, we're done. Otherwise, restart // the loop with the reduced length so we return the // remnants in the output buffer. len = outputBuffer.remaining(); if (len == 0) { return -1; } } else { for (int i = 0; i < charsRead; i++) { char ch = inputBuffer[i]; if (check(ch)) { // Valid character, encode it into the output // buffer. outputBufferWriter.write(((int) ch) & 0xFFFF); } else { // Invalid character FarragoTrace.getMdrTracer().fine( "Invalid XML character: " + Integer.toHexString(ch)); numInvalidCharsFiltered++; } } // Flush the buffer to make sure all bytes reach the // actual output buffer. outputBufferWriter.flush(); } } } } @Override public long skip(long n) throws IOException { long skip = 0; while (skip < n) { if (read() < 0) { break; } skip++; } return skip; } public int getNumInvalidCharsFiltered() { return numInvalidCharsFiltered; } /** * ByteOutputStream extends ByteArrayOutputStream to provide * ByteBuffer-like operations such as compact, array and get. */ private static class ByteOutputStream extends ByteArrayOutputStream { private int pos; public ByteOutputStream(int initialBufferSize) { super(initialBufferSize); this.pos = 0; } public void size(int size) { super.count = Math.min(size, super.buf.length); } public byte [] array() { return super.buf; } public byte get() { return super.buf[pos++]; } public void get(byte [] b, int off, int len) { if (len > remaining()) { throw new IndexOutOfBoundsException(); } System.arraycopy(super.buf, pos, b, off, len); pos += len; } public int remaining() { return size() - pos; } @Override public void reset() { super.reset(); pos = 0; } public void compact() { int rem = remaining(); if (rem > 0) { System.arraycopy(super.buf, pos, super.buf, 0, rem); } size(rem); pos = 0; } } } } // End FarragoReposUtil.java eigenbase-farrago-0.9.0/src/net/sf/farrago/package.html0000444000175000017500000000456611173714170022657 0ustar drazzibdrazzib Package net.sf.farrago Top-level package containing all Farrago subpackages.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/package.html#20 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi


The UML diagram below illustrates the dependencies among Farrago subpackages:

Transitive depenencies are mostly left out (so if package A depends on package B, and package B depends on C, it's implied that package A may depend on package C as well). In this context, dependency means early binding; that is, the higher-level package references the lower-level package at compile time. Packages with italicized names are interface packages.

Note that the farrago.trace package is special in that it is allowed (and in fact required) to participate in circular dependencies with other packages.

TBD: dependencies on packages like java.sql, org.eigenbase, and MDR. Also need to show com.disruptivetech.**, com.lucidera.**. And:

  • farrago.jdbc depends on farrago.release
  • farrago.jdbc.client depends on farrago.fennel.tuple
  • farrago.util depends on farrago.release
  • farrago.runtime depends on farrago.jdbc.params

Dependencies are checked via the macker tool as part of Farrago checkin acceptance tests. Dependency definitions are in //open/dev/farrago/src/macker.xml.

Note that late binding is allowed to violate the layering. For example, the util layer defines the {@link net.sf.farrago.util.FarragoAllocation} interface. The db layer defines class {@link net.sf.farrago.db.FarragoDbStmtContext}, which implements FarragoAllocation, and passes an instance to {@link net.sf.farrago.util.FarragoCompoundAllocation}. When the FarragoCompoundAllocation is closed, it calls back via the interface, meaning at runtime, code in the util layer ends up calling code in the db layer.


eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/0000755000175000017500000000000011173714170022005 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/package.html0000444000175000017500000000111111173714170024256 0ustar drazzibdrazzib Package net.sf.farrago.defimpl Defines the default component set for the Farrago reference implementation.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/package.html#6 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/FarragoDefaultHeuristicPlanner.java0000444000175000017500000003515211173714170030742 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultHeuristicPlanner.java#22 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.defimpl; import net.sf.farrago.fennel.rel.*; import com.lucidera.opt.*; import java.util.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.query.*; import net.sf.farrago.session.*; import org.eigenbase.oj.rel.*; import org.eigenbase.rel.*; import org.eigenbase.rel.rules.*; import org.eigenbase.relopt.*; import org.eigenbase.relopt.hep.*; /** * FarragoDefaultHeuristicPlanner implements {@link FarragoSessionPlanner} in * terms of {@link HepPlanner} with a Farrago-specific rule program. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultHeuristicPlanner.java#22 $ */ public class FarragoDefaultHeuristicPlanner extends HepPlanner implements FarragoSessionPlanner { //~ Instance fields -------------------------------------------------------- private final FarragoSessionPreparingStmt stmt; private final Collection medPluginRules; private boolean inPluginRegistration; //~ Constructors ----------------------------------------------------------- public FarragoDefaultHeuristicPlanner( HepProgram program, FarragoSessionPreparingStmt stmt, Collection medPluginRules) { super(program); this.stmt = stmt; this.medPluginRules = medPluginRules; } //~ Methods ---------------------------------------------------------------- static FarragoDefaultHeuristicPlanner newInstance( FarragoSessionPreparingStmt stmt) { Collection medPluginRules = new LinkedHashSet(); final boolean fennelEnabled = stmt.getRepos().isFennelEnabled(); final CalcVirtualMachine calcVM = stmt.getRepos().getCurrentConfig().getCalcVirtualMachine(); HepProgram program = createHepProgram( fennelEnabled, calcVM, medPluginRules); FarragoDefaultHeuristicPlanner planner = new FarragoDefaultHeuristicPlanner( program, stmt, medPluginRules); FarragoDefaultPlanner.addStandardRules(planner, fennelEnabled, calcVM); return planner; } // implement FarragoSessionPlanner public FarragoSessionPreparingStmt getPreparingStmt() { return stmt; } // implement FarragoSessionPlanner public void beginMedPluginRegistration(String serverClassName) { inPluginRegistration = true; } // implement FarragoSessionPlanner public void endMedPluginRegistration() { inPluginRegistration = false; } // implement RelOptPlanner public JavaRelImplementor getJavaRelImplementor(RelNode rel) { return stmt.getRelImplementor( rel.getCluster().getRexBuilder()); } // implement RelOptPlanner public boolean addRule(RelOptRule rule) { if (inPluginRegistration) { medPluginRules.add(rule); } return super.addRule(rule); } private static HepProgram createHepProgram( boolean fennelEnabled, CalcVirtualMachine calcVM, Collection medPluginRules) { HepProgramBuilder builder = new HepProgramBuilder(); // The very first step is to implement index joins on catalog // tables. The reason we do this here is so that we don't // disturb the carefully hand-coded joins in the catalog views. // TODO: loosen up builder.addRuleByDescription("MedMdrJoinRule"); // Eliminate AGG(DISTINCT x) now, because this transformation // may introduce new joins which need to be optimized further on. builder.addRuleInstance(RemoveDistinctAggregateRule.instance); // Eliminate reducible constant expression. TODO jvs 26-May-2006: do // this again later wherever more such expressions may be reintroduced. builder.addRuleClass(FarragoReduceExpressionsRule.class); // Now, pull join conditions out of joins, leaving behind Cartesian // products. Why? Because PushFilterRule doesn't start from // join conditions, only filters. It will push them right back // into and possibly through the join. builder.addRuleInstance(ExtractJoinFilterRule.instance); // Remove trivial projects so tables referenced in selects in the // from clause can be optimized with the rest of the query builder.addRuleInstance(RemoveTrivialProjectRule.instance); // Push filters. builder.addGroupBegin(); builder.addRuleInstance(PushFilterPastSetOpRule.instance); builder.addRuleInstance(PushFilterPastProjectRule.instance); builder.addRuleInstance( new PushFilterPastJoinRule( new RelOptRuleOperand( FilterRel.class, new RelOptRuleOperand(JoinRel.class, RelOptRule.ANY)), "with filter above join")); builder.addRuleInstance( new PushFilterPastJoinRule( new RelOptRuleOperand(JoinRel.class, RelOptRule.ANY), "without filter above join")); builder.addRuleInstance(MergeFilterRule.instance); builder.addGroupEnd(); // This rule will also get run as part of medPluginRules, but // we need to do it now before pushing down projections, otherwise // a projection can get in the way of a filter. builder.addRuleByDescription("FtrsScanToSearchRule"); // Use index joins in preference to hash joins. This rule will // also get run as part of medPluginRules, but we want to preempt // that to make sure some of the other FTRS rules don't fire // first, preventing usage of the join. builder.addRuleByDescription("FtrsIndexJoinRule"); // Push projections down. Do this after index joins, because // index joins don't like projections underneath the join. builder.addGroupBegin(); builder.addRuleInstance(RemoveTrivialProjectRule.instance); builder.addRuleInstance(PushProjectPastSetOpRule.instance); builder.addRuleInstance(PushProjectPastJoinRule.instance); builder.addRuleInstance(PushProjectPastFilterRule.instance); builder.addRuleInstance(MergeProjectRule.instance); builder.addGroupEnd(); // Eliminate UNION DISTINCT and trivial UNION. builder.addRuleInstance(UnionToDistinctRule.instance); builder.addRuleInstance(UnionEliminatorRule.instance); // Eliminate redundant SELECT DISTINCT. builder.addRuleInstance(RemoveDistinctRule.instance); // We're getting close to physical implementation. First, insert // type coercions for expressions which require it. builder.addRuleClass(CoerceInputsRule.class); // Run any SQL/MED plugin rules. Note that // some of these may rely on CoerceInputsRule above. builder.addRuleCollection(medPluginRules); builder.addRuleInstance(RemoveTrivialProjectRule.instance); // Use hash semi join if possible. builder.addRuleInstance(LhxSemiJoinRule.instance); // Use hash join where possible. Make sure this rule is called before // any physical conversions have been done builder.addRuleInstance(LhxJoinRule.instance); // Use hash join to implement set op: Intersect. builder.addRuleInstance(LhxIntersectRule.instance); // Use hash join to implement set op: Except(minus). builder.addRuleInstance(LhxMinusRule.instance); // Use nested loop join if hash join can't be used if (fennelEnabled) { builder.addRuleInstance(FennelNestedLoopJoinRule.instance); } // Extract join conditions again so that FennelCartesianJoinRule can do // its job. Need to do this before converting filters to calcs, but // after other join strategies such as hash join have been attempted, // because they rely on the join condition being part of the join. builder.addRuleInstance(ExtractJoinFilterRule.instance); // Change "is not distinct from" condition to a case expression // which can be evaluated by CalcRel. builder.addRuleInstance(RemoveIsNotDistinctFromRule.instance); // Replace AVG with SUM/COUNT (need to do this BEFORE calc conversion // and decimal reduction). builder.addRuleInstance(ReduceAggregatesRule.instance); // Prefer hash aggregation over the standard Fennel aggregation. builder.addRuleInstance(LhxAggRule.instance); // Handle trivial renames now so that they don't get // implemented as calculators. if (fennelEnabled) { builder.addRuleInstance(FennelRenameRule.instance); } // Convert remaining filters and projects to logical calculators, // merging adjacent ones. Calculator expressions containing // multisets and windowed aggs may yield new projections, // so run all these rules together until fixpoint. builder.addGroupBegin(); builder.addRuleInstance(FilterToCalcRule.instance); builder.addRuleInstance(ProjectToCalcRule.instance); builder.addRuleInstance(MergeCalcRule.instance); builder.addRuleInstance(WindowedAggSplitterRule.instance); builder.addRuleInstance(FarragoMultisetSplitterRule.instance); builder.addGroupEnd(); // These rules handle expressions which can be introduced by multiset // rewrite, which is why they repeat earlier ones. builder.addRuleClass(CoerceInputsRule.class); builder.addRuleInstance(UnionToDistinctRule.instance); builder.addRuleInstance(UnionEliminatorRule.instance); builder.addRuleInstance(RemoveDistinctRule.instance); // First, try to use ReshapeRel for calcs before firing the other // physical calc conversion rules. Fire this rule before // ReduceDecimalsRule so we avoid decimal reinterprets that can // be handled by Reshape if (fennelEnabled) { builder.addRuleInstance(FennelReshapeRule.instance); } // Replace the DECIMAL datatype with primitive ints. builder.addRuleInstance(ReduceDecimalsRule.instance); // NOTE jvs 8-Jan-2008: FennelDistinctSortRule is now // redundant with LhxAggRule above. // Implement DISTINCT via tree-sort instead of letting it // be handled via normal sort plus agg. builder.addRuleInstance(FennelDistinctSortRule.instance); // The rest of these are all physical implementation rules // which are safe to apply simultaneously. builder.addGroupBegin(); // Implement calls to UDX's. builder.addRuleInstance(FarragoJavaUdxRule.instance); if (fennelEnabled) { builder.addRuleInstance(FennelSortRule.instance); builder.addRuleInstance(FennelRenameRule.instance); builder.addRuleInstance(FennelCartesianJoinRule.instance); // NOTE jvs 8-Jan-2008: FennelAggRule is now redundant with // LhxAggRule above. builder.addRuleInstance(FennelAggRule.instance); builder.addRuleInstance(FennelCollectRule.instance); builder.addRuleInstance(FennelUncollectRule.instance); builder.addRuleInstance(FennelCorrelatorRule.instance); builder.addRuleInstance(FennelValuesRule.instance); builder.addRuleInstance(FennelEmptyRule.instance); builder.addRuleInstance(FennelBernoulliSamplingRule.instance); } else { builder.addRuleInstance( IterRules.HomogeneousUnionToIteratorRule.instance); } if (calcVM.equals(CalcVirtualMachineEnum.CALCVM_FENNEL)) { // use Fennel for calculating expressions assert (fennelEnabled); builder.addRuleInstance(FennelCalcRule.instance); builder.addRuleInstance(FennelOneRowRule.instance); // NOTE jvs 3-May-2006: See corresponding REVIEW comment in // FarragoDefaultPlanner about why this goes here. builder.addRuleInstance(FennelUnionRule.instance); } else if (calcVM.equals(CalcVirtualMachineEnum.CALCVM_JAVA)) { // use Java code generation for calculating expressions builder.addRuleInstance(IterRules.IterCalcRule.instance); builder.addRuleInstance(IterRules.OneRowToIteratorRule.instance); builder.addRuleInstance( IterRules.HomogeneousUnionToIteratorRule.instance); } // Finish main physical implementation group. builder.addGroupEnd(); // If automatic calculator selection is enabled (the default), // figure out what to do with CalcRels. if (calcVM.equals(CalcVirtualMachineEnum.CALCVM_AUTO)) { // First, attempt to choose calculators such that converters are // minimized builder.addConverters(false); // Split remaining expressions into Fennel part and Java part builder.addRuleInstance(FarragoAutoCalcRule.instance); // Convert expressions, giving preference to Java builder.addRuleInstance(IterRules.OneRowToIteratorRule.instance); builder.addRuleInstance(IterRules.IterCalcRule.instance); builder.addRuleInstance(FennelCalcRule.instance); // Use Fennel for unions. builder.addRuleInstance(FennelUnionRule.instance); } // Finally, add generic converters as necessary. builder.addConverters(true); return builder.createProgram(); } } // End FarragoDefaultHeuristicPlanner.java eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/FarragoVolcanoPersonalityFactory.java0000444000175000017500000000512411173714170031335 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoVolcanoPersonalityFactory.java#6 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.defimpl; import net.sf.farrago.db.*; import net.sf.farrago.session.*; /** * FarragoVolcanoPersonalityFactory implements the {@link * FarragoSessionPersonalityFactory} interface by using Volcano to implement * cost-based optimization. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoVolcanoPersonalityFactory.java#6 $ */ public class FarragoVolcanoPersonalityFactory implements FarragoSessionPersonalityFactory { //~ Methods ---------------------------------------------------------------- // implement FarragoSessionPersonalityFactory public FarragoSessionPersonality newSessionPersonality( FarragoSession session, FarragoSessionPersonality defaultPersonality) { return new FarragoVolcanoSessionPersonality((FarragoDbSession) session); } //~ Inner Classes ---------------------------------------------------------- private static class FarragoVolcanoSessionPersonality extends FarragoDefaultSessionPersonality { protected FarragoVolcanoSessionPersonality(FarragoDbSession session) { super(session); } // implement FarragoSessionPersonality public FarragoSessionPlanner newPlanner( FarragoSessionPreparingStmt stmt, boolean init) { FarragoDefaultPlanner planner = new FarragoDefaultPlanner(stmt); if (init) { planner.init(); } return planner; } } } // End FarragoVolcanoPersonalityFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/FarragoDefaultPlanner.java0000444000175000017500000001202611173714170027055 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultPlanner.java#41 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.defimpl; import net.sf.farrago.fennel.rel.*; import org.eigenbase.relopt.volcano.*; import net.sf.farrago.fem.config.*; import net.sf.farrago.query.*; import net.sf.farrago.session.*; import org.eigenbase.oj.rel.*; import org.eigenbase.rel.*; import org.eigenbase.rel.rules.*; import org.eigenbase.relopt.*; // TODO jvs 3-May-2006: Rename this to FarragoDefaultVolcanoPlanner /** * FarragoDefaultPlanner extends {@link VolcanoPlanner} to request * Farrago-specific optimizations. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultPlanner.java#41 $ */ public class FarragoDefaultPlanner extends VolcanoPlanner implements FarragoSessionPlanner { //~ Instance fields -------------------------------------------------------- private FarragoPreparingStmt stmt; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoDefaultPlanner object. * * @param stmt statement on whose behalf this planner operates */ public FarragoDefaultPlanner(FarragoSessionPreparingStmt stmt) { this.stmt = (FarragoPreparingStmt) stmt; // Yon Cassius has a lean and hungry look. ambitious = true; // Create a new CallingConvention trait definition that will store // the graph of possible conversions and handle the creation of // converters. addRelTraitDef(CallingConventionTraitDef.instance); // NOTE: don't call IterConverterRel.init and friends; their presence // just confuses the optimizer, and we explicitly supply all the // conversion rules we need RelOptUtil.registerAbstractRels(this); addRule(AbstractConverter.ExpandConversionRule.instance); } //~ Methods ---------------------------------------------------------------- /** * Initializes Farrago-specific rules for this planner. */ public void init() { final boolean fennelEnabled = stmt.getRepos().isFennelEnabled(); final CalcVirtualMachine calcVM = stmt.getRepos().getCurrentConfig().getCalcVirtualMachine(); addStandardRules(this, fennelEnabled, calcVM); } /** * Adds a set of standard rules to a planner. * * @param planner Planner * @param fennelEnabled Whether fennel is enabled. * @param calcVM Flavor of calculator being used. */ public static void addStandardRules( FarragoSessionPlanner planner, boolean fennelEnabled, CalcVirtualMachine calcVM) { FarragoStandardPlannerRules.addDefaultRules( planner, fennelEnabled, calcVM); planner.addRule(FarragoMultisetSplitterRule.instance); if (fennelEnabled) { planner.addRule(FennelCollectRule.instance); planner.addRule(FennelUncollectRule.instance); planner.addRule(FennelCorrelatorRule.instance); } } // NOTE jvs 22-Mar-2007: separate method from // FarragoStandardPlannerRules.addStandardRules to avoid direct dependency // on com.disruptivetech from there public static void addFennelCalcRules( FarragoSessionPlanner planner, boolean auto) { planner.addRule(FennelCalcRule.instance); if (auto) { planner.addRule(FarragoAutoCalcRule.instance); } } // implement FarragoSessionPlanner public FarragoSessionPreparingStmt getPreparingStmt() { return stmt; } // implement FarragoSessionPlanner public void beginMedPluginRegistration(String serverClassName) { // don't care } // implement FarragoSessionPlanner public void endMedPluginRegistration() { // don't care } // override VolcanoPlanner public JavaRelImplementor getJavaRelImplementor(RelNode rel) { return stmt.getRelImplementor(rel.getCluster().getRexBuilder()); } } // End FarragoDefaultPlanner.java eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/FarragoStandardPlannerRules.java0000444000175000017500000001477611173714170030262 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoStandardPlannerRules.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2007-2009 The Eigenbase Project // Copyright (C) 2007-2009 SQLstream, Inc. // Copyright (C) 2007-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.defimpl; import net.sf.farrago.fem.config.*; import net.sf.farrago.fennel.rel.*; import net.sf.farrago.query.*; import net.sf.farrago.session.*; import org.eigenbase.oj.rel.*; import org.eigenbase.rel.*; import org.eigenbase.rel.rules.*; import org.eigenbase.relopt.*; /** * Registers standard rules needed by most planner implementations. * * @author John Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoStandardPlannerRules.java#7 $ */ public class FarragoStandardPlannerRules { //~ Methods ---------------------------------------------------------------- /** * Adds a set of default rules to a planner. * * @param planner Planner * @param fennelEnabled Whether fennel is enabled. * @param calcVM Flavor of calculator being used. */ public static void addDefaultRules( FarragoSessionPlanner planner, boolean fennelEnabled, CalcVirtualMachine calcVM) { planner.addRule(RemoveDistinctRule.instance); planner.addRule(RemoveDistinctAggregateRule.instance); planner.addRule(ExtractJoinFilterRule.instance); planner.addRule(UnionToDistinctRule.instance); planner.addRule(UnionEliminatorRule.instance); // for set operations, we coerce names to match so that // Java implementations can pass row objects through without // copying planner.addRule(new CoerceInputsRule(UnionRel.class, true)); planner.addRule(new CoerceInputsRule(IntersectRel.class, true)); planner.addRule(new CoerceInputsRule(MinusRel.class, true)); // for DML, name coercion isn't helpful planner.addRule( new CoerceInputsRule(TableModificationRel.class, false)); planner.addRule(SwapJoinRule.instance); planner.addRule(RemoveTrivialProjectRule.instance); planner.addRule(RemoveTrivialCalcRule.instance); planner.addRule(FarragoJavaUdxRule.instance); planner.addRule(IterRules.HomogeneousUnionToIteratorRule.instance); planner.addRule(IterRules.OneRowToIteratorRule.instance); planner.addRule(ReduceDecimalsRule.instance); planner.addRule(FarragoReduceExpressionsRule.filterInstance); planner.addRule(FarragoReduceExpressionsRule.projectInstance); planner.addRule(FarragoReduceExpressionsRule.joinInstance); planner.addRule(FarragoReduceExpressionsRule.calcInstance); planner.addRule(FarragoReduceValuesRule.filterInstance); planner.addRule(FarragoReduceValuesRule.projectInstance); planner.addRule(FarragoReduceValuesRule.projectFilterInstance); planner.addRule(ReduceAggregatesRule.instance); // NOTE zfong 9/27/06: PullUpProjectsAboveJoinRule has not been // added because together with PushProjectPastJoinRule, it causes // Volcano to go into an infinite loop planner.addRule(PushFilterPastJoinRule.instance); planner.addRule(PushFilterPastSetOpRule.instance); planner.addRule(MergeFilterRule.instance); planner.addRule(PushFilterPastProjectRule.instance); planner.addRule(PushProjectPastFilterRule.instance); planner.addRule(PushProjectPastJoinRule.instance); planner.addRule(PushProjectPastSetOpRule.instance); planner.addRule(MergeProjectRule.instance); if (fennelEnabled) { planner.addRule(FennelSortRule.instance); planner.addRule(FennelDistinctSortRule.instance); planner.addRule(FennelRenameRule.instance); planner.addRule(FennelCartesianJoinRule.instance); planner.addRule(FennelOneRowRule.instance); planner.addRule(FennelValuesRule.instance); planner.addRule(FennelEmptyRule.instance); planner.addRule(FennelAggRule.instance); planner.addRule(FennelReshapeRule.instance); } // Add the rule to introduce FennelCalcRel's only if the fennel // calculator is enabled. if (calcVM.equals(CalcVirtualMachineEnum.CALCVM_FENNEL)) { // use Fennel for calculating expressions assert fennelEnabled; FarragoDefaultPlanner.addFennelCalcRules(planner, false); // REVIEW jvs 13-Nov-2005: I put FennelUnionRule here instead of in // fennelEnabled block above because I want to be able to test both // implementations, and currently the only way to control that is // via the calc parameter. Probably need a more general parameter // controlling all rels in case of overlap, not just calc. planner.addRule(FennelUnionRule.instance); } if (calcVM.equals(CalcVirtualMachineEnum.CALCVM_JAVA) || calcVM.equals(CalcVirtualMachineEnum.CALCVM_AUTO)) { // use Java code generation for calculating expressions planner.addRule(IterRules.IterCalcRule.instance); } if (calcVM.equals(CalcVirtualMachineEnum.CALCVM_AUTO) && fennelEnabled) { // add rule for pure calculator usage plus rule for // decomposing rels into mixed Java/Fennel impl FarragoDefaultPlanner.addFennelCalcRules(planner, true); // see REVIEW 13-Nov-2005 comment above planner.addRule(FennelUnionRule.instance); } if (fennelEnabled) { FennelToIteratorConverter.register(planner); IteratorToFennelConverter.register(planner); } } } // End FarragoStandardPlannerRules.java eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/FarragoDefaultSessionFactory.java0000444000175000017500000000420311173714170030427 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultSessionFactory.java#10 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2004-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.defimpl; import java.util.*; import net.sf.farrago.db.*; import net.sf.farrago.session.*; /** * FarragoDefaultSessionFactory provides a default implementation for the {@link * FarragoSessionFactory} interface. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultSessionFactory.java#10 $ */ public class FarragoDefaultSessionFactory extends FarragoDbSessionFactory { //~ Methods ---------------------------------------------------------------- // implement FarragoSessionFactory public FarragoSession newSession( String url, Properties info) { return new FarragoDbSession( url, info, this); } // implement FarragoSessionPersonalityFactory public FarragoSessionPersonality newSessionPersonality( FarragoSession session, FarragoSessionPersonality defaultPersonality) { return new FarragoDefaultSessionPersonality((FarragoDbSession) session); } } // End FarragoDefaultSessionFactory.java eigenbase-farrago-0.9.0/src/net/sf/farrago/defimpl/FarragoDefaultSessionPersonality.java0000444000175000017500000006502511173714170031342 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultSessionPersonality.java#54 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.defimpl; import net.sf.farrago.fennel.calc.*; import com.lucidera.farrago.fennel.*; import org.eigenbase.lurql.*; import java.io.*; import java.sql.*; import java.util.*; import javax.jmi.reflect.*; import net.sf.farrago.catalog.*; import net.sf.farrago.cwm.core.*; import net.sf.farrago.cwm.relational.*; import net.sf.farrago.cwm.relational.enumerations.*; import net.sf.farrago.db.*; import net.sf.farrago.ddl.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.fem.security.*; import net.sf.farrago.fem.sql2003.*; import net.sf.farrago.namespace.util.*; import net.sf.farrago.parser.*; import net.sf.farrago.query.*; import net.sf.farrago.resource.*; import net.sf.farrago.runtime.*; import net.sf.farrago.session.*; import net.sf.farrago.type.*; import org.eigenbase.jmi.*; import org.eigenbase.oj.rex.*; import org.eigenbase.rel.*; import org.eigenbase.rel.metadata.*; import org.eigenbase.reltype.*; import org.eigenbase.resgen.*; import org.eigenbase.resource.*; import org.eigenbase.sql.*; import org.eigenbase.sql.fun.*; import org.eigenbase.sql.type.*; import org.eigenbase.util.*; import org.eigenbase.util14.*; /** * FarragoDefaultSessionPersonality is a default implementation of the {@link * FarragoSessionPersonality} interface. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/defimpl/FarragoDefaultSessionPersonality.java#54 $ */ public class FarragoDefaultSessionPersonality implements FarragoSessionPersonality { //~ Static fields/initializers --------------------------------------------- // REVIEW jvs 8-May-2007: These are referenced from various // places where it seems like macker should prevent the dependency. // Not sure why that is, but figure out a better place for them // (probably FarragoSessionVariables), leaving these here as aliases. /** * Numeric data from external data sources may have a greater precision than * Farrago. Whether data of greater precision should be replaced with null * when it overflows due to the greater precision. */ public static final String SQUEEZE_JDBC_NUMERIC = "squeezeJdbcNumeric"; public static final String SQUEEZE_JDBC_NUMERIC_DEFAULT = "true"; /** * Whether statement caching is enabled for a session */ public static final String CACHE_STATEMENTS = "cacheStatements"; public static final String CACHE_STATEMENTS_DEFAULT = "true"; /** * Whether DDL validation should be done at prepare time */ public static final String VALIDATE_DDL_ON_PREPARE = "validateDdlOnPrepare"; public static final String VALIDATE_DDL_ON_PREPARE_DEFAULT = "false"; /** * Whether non-correlated subqueries should be converted to constants */ public static final String REDUCE_NON_CORRELATED_SUBQUERIES = "reduceNonCorrelatedSubqueries"; public static final String REDUCE_NON_CORRELATED_SUBQUERIES_FARRAGO_DEFAULT = "false"; /** * Degree of parallelism to use for parallel executor; a value of 1 (the * default) causes the default non-parallel executor to be used. */ public static final String DEGREE_OF_PARALLELISM = "degreeOfParallelism"; public static final String DEGREE_OF_PARALLELISM_DEFAULT = "1"; /** * The label for the current session */ public static final String LABEL = "label"; public static final String LABEL_DEFAULT = null; //~ Instance fields -------------------------------------------------------- protected final FarragoDatabase database; protected final ParamValidator paramValidator; //~ Constructors ----------------------------------------------------------- protected FarragoDefaultSessionPersonality(FarragoDbSession session) { database = session.getDatabase(); paramValidator = new ParamValidator(); paramValidator.registerBoolParam( SQUEEZE_JDBC_NUMERIC, false); paramValidator.registerBoolParam( CACHE_STATEMENTS, false); paramValidator.registerBoolParam( VALIDATE_DDL_ON_PREPARE, false); paramValidator.registerBoolParam( REDUCE_NON_CORRELATED_SUBQUERIES, false); paramValidator.registerStringParam(LABEL, true); paramValidator.registerIntParam( DEGREE_OF_PARALLELISM, false, 1, Integer.MAX_VALUE); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionPersonality public FarragoSessionPlanner newPlanner( FarragoSessionPreparingStmt stmt, boolean init) { return FarragoDefaultHeuristicPlanner.newInstance(stmt); } // implement FarragoSessionPersonality public void definePlannerListeners(FarragoSessionPlanner planner) { } // implement FarragoStreamFactoryProvider public void registerStreamFactories(long hStreamGraph) { LucidEraJni.registerStreamFactory(hStreamGraph); } // implement FarragoSessionPersonality public String getDefaultLocalDataServerName( FarragoSessionStmtValidator stmtValidator) { if (stmtValidator.getSession().getRepos().isFennelEnabled()) { return "SYS_FTRS_DATA_SERVER"; } else { return "SYS_MOCK_DATA_SERVER"; } } // implement FarragoSessionPersonality public boolean isAlterTableAddColumnIncremental() { return false; } // implement FarragoSessionPersonality public SqlOperatorTable getSqlOperatorTable( FarragoSessionPreparingStmt preparingStmt) { return SqlStdOperatorTable.instance(); } // implement FarragoSessionPersonality public OJRexImplementorTable getOJRexImplementorTable( FarragoSessionPreparingStmt preparingStmt) { return database.getOJRexImplementorTable(); } // implement FarragoSessionPersonality public C newComponentImpl(Class componentInterface) { if (componentInterface == CalcRexImplementorTable.class) { return componentInterface.cast(CalcRexImplementorTableImpl.std()); } return null; } // implement FarragoSessionPersonality public FarragoSessionParser newParser(FarragoSession session) { return new FarragoParser(); } // implement FarragoSessionPersonality public FarragoSessionPreparingStmt newPreparingStmt( FarragoSessionStmtValidator stmtValidator) { return newPreparingStmt(null, stmtValidator); } // implement FarragoSessionPersonality public FarragoSessionPreparingStmt newPreparingStmt( FarragoSessionStmtContext stmtContext, FarragoSessionStmtValidator stmtValidator) { return newPreparingStmt(stmtContext, stmtContext, stmtValidator); } // implement FarragoSessionPersonality public FarragoSessionPreparingStmt newPreparingStmt( FarragoSessionStmtContext stmtContext, FarragoSessionStmtContext rootStmtContext, FarragoSessionStmtValidator stmtValidator) { // NOTE: We don't use stmtContext here (except to obtain the SQL text), // and we don't pass it on to the // preparing statement, because that doesn't need to be aware of its // context. However, custom personalities may have a use for it, which // is why it is provided in the interface. String sql = (stmtContext == null) ? "?" : stmtContext.getSql(); FarragoPreparingStmt stmt = new FarragoPreparingStmt( rootStmtContext, stmtValidator, sql); initPreparingStmt(stmt); return stmt; } protected void initPreparingStmt(FarragoPreparingStmt stmt) { FarragoSessionStmtValidator stmtValidator = stmt.getStmtValidator(); FarragoSessionPlanner planner = stmtValidator.getSession().getPersonality().newPlanner(stmt, true); planner.setRuleDescExclusionFilter( stmtValidator.getSession().getOptRuleDescExclusionFilter()); stmt.setPlanner(planner); } // implement FarragoSessionPersonality public FarragoSessionDdlValidator newDdlValidator( FarragoSessionStmtValidator stmtValidator) { return new DdlValidator(stmtValidator); } // implement FarragoSessionPersonality public void defineDdlHandlers( FarragoSessionDdlValidator ddlValidator, List handlerList) { // NOTE jvs 21-Jan-2005: handlerList order matters here. // DdlRelationalHandler includes some catch-all methods for // superinterfaces which we only want to invoke when one of // the more specific handlers doesn't satisfied the request. DdlMedHandler medHandler = new DdlMedHandler(ddlValidator); DdlSecurityHandler securityHandler = new DdlSecurityHandler(ddlValidator); handlerList.add(medHandler); handlerList.add(new DdlRoutineHandler(ddlValidator)); handlerList.add(securityHandler); handlerList.add(new DdlRelationalHandler(medHandler)); // Define drop rules FarragoRepos repos = ddlValidator.getStmtValidator().getSession().getRepos(); // When a table is dropped, all indexes on the table should also be // implicitly dropped. ddlValidator.defineDropRule( repos.getKeysIndexesPackage().getIndexSpansClass(), new FarragoSessionDdlDropRule( "spannedClass", null, ReferentialRuleTypeEnum.IMPORTED_KEY_CASCADE)); // Dependencies can never be dropped without CASCADE, but with // CASCADE, they go away. ddlValidator.defineDropRule( repos.getCorePackage().getDependencySupplier(), new FarragoSessionDdlDropRule( "supplier", null, ReferentialRuleTypeEnum.IMPORTED_KEY_RESTRICT)); // When a dependency gets dropped, take its owner (the client) // down with it. ddlValidator.defineDropRule( repos.getCorePackage().getElementOwnership(), new FarragoSessionDdlDropRule( "ownedElement", CwmDependency.class, ReferentialRuleTypeEnum.IMPORTED_KEY_CASCADE)); // Without CASCADE, a schema can only be dropped when it is empty. // This is not true for other namespaces (e.g. a table's constraints // are dropped implicitly), so we specify the superInterface filter. ddlValidator.defineDropRule( repos.getCorePackage().getElementOwnership(), new FarragoSessionDdlDropRule( "namespace", CwmSchema.class, ReferentialRuleTypeEnum.IMPORTED_KEY_RESTRICT)); // When a UDT is dropped, all routines which realize methods should // also be implicitly dropped. ddlValidator.defineDropRule( repos.getBehavioralPackage().getOperationMethod(), new FarragoSessionDdlDropRule( "specification", null, ReferentialRuleTypeEnum.IMPORTED_KEY_CASCADE)); // Grants should be dropped together with any of the grantor, grantee, // or granted element ddlValidator.defineDropRule( repos.getSecurityPackage().getPrivilegeIsGrantedToGrantee(), new FarragoSessionDdlDropRule( "Grantee", null, ReferentialRuleTypeEnum.IMPORTED_KEY_CASCADE)); ddlValidator.defineDropRule( repos.getSecurityPackage().getPrivilegeIsGrantedByGrantor(), new FarragoSessionDdlDropRule( "Grantor", null, ReferentialRuleTypeEnum.IMPORTED_KEY_CASCADE)); ddlValidator.defineDropRule( repos.getSecurityPackage().getPrivilegeIsGrantedOnElement(), new FarragoSessionDdlDropRule( "Element", null, ReferentialRuleTypeEnum.IMPORTED_KEY_CASCADE)); // Drop the corresponding label aliases if the cascade option // was specified ddlValidator.defineDropRule( repos.getMedPackage().getLabelHasAlias(), new FarragoSessionDdlDropRule( "ParentLabel", null, ReferentialRuleTypeEnum.IMPORTED_KEY_RESTRICT)); } // implement FarragoSessionPersonality public void definePrivileges( FarragoSessionPrivilegeMap map) { FarragoRepos repos = database.getSystemRepos(); PrivilegedAction [] tableActions = new PrivilegedAction[] { PrivilegedActionEnum.SELECT, PrivilegedActionEnum.INSERT, PrivilegedActionEnum.DELETE, PrivilegedActionEnum.UPDATE, }; defineTypePrivileges( map, repos.getRelationalPackage().getCwmNamedColumnSet(), tableActions); PrivilegedAction [] routineActions = new PrivilegedAction[] { PrivilegedActionEnum.EXECUTE }; defineTypePrivileges( map, repos.getSql2003Package().getFemRoutine(), routineActions); } private void defineTypePrivileges( FarragoSessionPrivilegeMap map, RefClass refClass, PrivilegedAction [] actions) { for (PrivilegedAction action : actions) { map.mapPrivilegeForType( refClass, action.toString(), true, true); } } // implement FarragoSessionPersonality public Class getRuntimeContextClass( FarragoSessionPreparingStmt preparingStmt) { return FarragoRuntimeContext.class; } // implement FarragoSessionPersonality public FarragoSessionRuntimeContext newRuntimeContext( FarragoSessionRuntimeParams params) { return new FarragoRuntimeContext(params); } // implement FarragoSessionPersonality public RelDataTypeFactory newTypeFactory( FarragoRepos repos) { return new FarragoTypeFactoryImpl(repos); } // implement FarragoSessionPersonality public void loadDefaultSessionVariables( FarragoSessionVariables variables) { variables.setDefault( SQUEEZE_JDBC_NUMERIC, SQUEEZE_JDBC_NUMERIC_DEFAULT); variables.setDefault( CACHE_STATEMENTS, CACHE_STATEMENTS_DEFAULT); variables.setDefault( VALIDATE_DDL_ON_PREPARE, VALIDATE_DDL_ON_PREPARE_DEFAULT); variables.setDefault( REDUCE_NON_CORRELATED_SUBQUERIES, REDUCE_NON_CORRELATED_SUBQUERIES_FARRAGO_DEFAULT); variables.setDefault(LABEL, LABEL_DEFAULT); variables.setDefault( DEGREE_OF_PARALLELISM, DEGREE_OF_PARALLELISM_DEFAULT); } // implement FarragoSessionPersonality public FarragoSessionVariables createInheritedSessionVariables( FarragoSessionVariables variables) { return variables.cloneVariables(); } // implement FarragoSessionPersonality public void validateSessionVariable( FarragoSessionDdlValidator ddlValidator, FarragoSessionVariables variables, String name, String value) { String validatedValue = paramValidator.validate(ddlValidator, name, value); variables.set(name, validatedValue); } // implement FarragoSessionPersonality public JmiQueryProcessor newJmiQueryProcessor(String language) { if (!language.equals("LURQL")) { return null; } return new LurqlQueryProcessor( database.getSystemRepos().getMdrRepos()); } public boolean isSupportedType(SqlTypeName type) { if (type == null) { // Not a SQL type -- may be a structured type, such as MULTISET. return true; } switch (type) { case BOOLEAN: case TINYINT: case SMALLINT: case INTEGER: case DATE: case TIME: case TIMESTAMP: case BIGINT: case VARCHAR: case VARBINARY: case MULTISET: case CHAR: case BINARY: case REAL: case FLOAT: case DOUBLE: case ROW: case DECIMAL: return true; case DISTINCT: default: return false; } } // implement FarragoSessionPersonality public boolean supportsFeature(ResourceDefinition feature) { // TODO jvs 20-Mar-2006: Fix this non-conforming behavior. According // to the JDBC spec, each statement in an autocommit connection is // supposed to execute in its own private transaction. Farrago's // support for this isn't done yet, so for now we prevent // multiple active statements on an autocommit connection // (unless a personality specifically enables it). ResourceDefinition maasFeature = EigenbaseResource.instance() .SQLConformance_MultipleActiveAutocommitStatements; if (feature == maasFeature) { return false; } // Farrago doesn't support MERGE if (feature == EigenbaseResource.instance().SQLFeature_F312) { return false; } // Farrago doesn't automatically update row counts if (feature == EigenbaseResource.instance().PersonalityManagesRowCount) { return false; } // Farrago doesn't support snapshots if (feature == EigenbaseResource.instance().PersonalitySupportsSnapshots) { return false; } if (feature == EigenbaseResource.instance().PersonalitySupportsLabels) { return false; } // By default, support everything except the above. return true; } // implement FarragoSessionPersonality public boolean shouldReplacePreserveOriginalSql() { return true; } // implement FarragoSessionPersonality public void registerRelMetadataProviders(ChainedRelMetadataProvider chain) { // Don't chain in FarragoRelMetadataProvider here; instead, // that happens inside of FarragoPreparingStmt so that // this provider gets low priority. } // implement FarragoSessionPersonality public void getRowCounts( ResultSet resultSet, List rowCounts, TableModificationRel.Operation tableModOp) throws SQLException { boolean found = resultSet.next(); assert (found); boolean nextRowCount = addRowCount(resultSet, rowCounts); if ((tableModOp == TableModificationRel.Operation.INSERT) && nextRowCount) { // if the insert is on a column store table, a second rowcount // may be returned, indicating the number of insert violations nextRowCount = addRowCount(resultSet, rowCounts); } assert (!nextRowCount); } protected boolean addRowCount(ResultSet resultSet, List rowCounts) throws SQLException { rowCounts.add(resultSet.getLong(1)); return resultSet.next(); } // implement FarragoSessionPersonality public long updateRowCounts( FarragoSession session, List tableName, List rowCounts, TableModificationRel.Operation tableModOp, FarragoSessionRuntimeContext runningContext) { long count = rowCounts.get(0); if (tableModOp == TableModificationRel.Operation.INSERT) { if (rowCounts.size() == 2) { count -= rowCounts.get(1); } } return count; } // implement FarragoSessionPersonality public void resetRowCounts(FemAbstractColumnSet table) { } // implement FarragoSessionPersonality public void updateIndexRoot( FemLocalIndex index, FarragoDataWrapperCache wrapperCache, FarragoSessionIndexMap baseIndexMap, Long newRoot) { // Drop old roots and update references to point to new roots baseIndexMap.dropIndexStorage(wrapperCache, index, false); baseIndexMap.setIndexRoot(index, newRoot); } //~ Inner Classes ---------------------------------------------------------- /** * ParamDesc represents a session parameter descriptor */ private class ParamDesc { int type; boolean nullability; Long rangeStart, rangeEnd; public ParamDesc(int type, boolean nullability) { this.type = type; this.nullability = nullability; } public ParamDesc(int type, boolean nullability, long start, long end) { this.type = type; this.nullability = nullability; rangeStart = start; rangeEnd = end; } } /** * ParamValidator is a basic session parameter validator */ public class ParamValidator { private final int BOOLEAN_TYPE = 1; private final int INT_TYPE = 2; private final int STRING_TYPE = 3; private final int DIRECTORY_TYPE = 4; private final int LONG_TYPE = 5; private Map params; public ParamValidator() { params = new HashMap(); } public void registerBoolParam(String name, boolean nullability) { params.put(name, new ParamDesc(BOOLEAN_TYPE, nullability)); } public void registerIntParam(String name, boolean nullability) { params.put(name, new ParamDesc(INT_TYPE, nullability)); } public void registerIntParam( String name, boolean nullability, int start, int end) { assert (start <= end); params.put(name, new ParamDesc(INT_TYPE, nullability, start, end)); } public void registerLongParam( String name, boolean nullability, long start, long end) { assert (start <= end); params.put(name, new ParamDesc(LONG_TYPE, nullability, start, end)); } public void registerStringParam(String name, boolean nullability) { params.put(name, new ParamDesc(STRING_TYPE, nullability)); } public void registerDirectoryParam(String name, boolean nullability) { params.put(name, new ParamDesc(DIRECTORY_TYPE, nullability)); } public String validate( FarragoSessionDdlValidator ddlValidator, String name, String value) { if (!params.containsKey(name)) { throw FarragoResource.instance().ValidatorUnknownSysParam.ex( ddlValidator.getRepos().getLocalizedObjectName(name)); } ParamDesc paramDesc = params.get(name); if (!paramDesc.nullability && (value == null)) { throw FarragoResource.instance().ValidatorSysParamTypeMismatch .ex( value, ddlValidator.getRepos().getLocalizedObjectName(name)); } else if (value == null) { return null; } // If this is the label variable, make sure snapshots are enabled. if (name.equals(FarragoDefaultSessionPersonality.LABEL)) { if (!supportsFeature( EigenbaseResource.instance() .PersonalitySupportsSnapshots)) { throw EigenbaseResource.instance() .PersonalitySupportsSnapshots.ex(); } } Object o; switch (paramDesc.type) { case BOOLEAN_TYPE: o = ConversionUtil.toBoolean(value); break; case INT_TYPE: o = Integer.valueOf(value); if (paramDesc.rangeStart != null) { Integer i = (Integer) o; if ((i < paramDesc.rangeStart) || (i > paramDesc.rangeEnd)) { throw FarragoResource.instance() .ParameterValueOutOfRange.ex(value, name); } } break; case LONG_TYPE: o = Long.valueOf(value); if (paramDesc.rangeStart != null) { Long l = (Long) o; if ((l < paramDesc.rangeStart) || (l > paramDesc.rangeEnd)) { throw FarragoResource.instance() .ParameterValueOutOfRange.ex(value, name); } } break; case STRING_TYPE: o = value; break; case DIRECTORY_TYPE: File dir = new File(value); if ((!dir.exists()) || (!dir.isDirectory())) { throw FarragoResource.instance().InvalidDirectory.ex( value); } if (!dir.canWrite()) { throw FarragoResource.instance().FileWriteFailed.ex(value); } o = dir.getPath(); break; default: throw Util.newInternal("invalid param type"); } return o.toString(); } } } // End FarragoDefaultSessionPersonality.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/0000755000175000017500000000000011173714170022050 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelOnlyTupleReader.java0000444000175000017500000000521111173714170027116 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelOnlyTupleReader.java#5 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import net.sf.farrago.fennel.tuple.*; /** * FennelOnlyTupleReader implements the FennelTupleReader interface for reading * tuples from a query plan that can be executed exclusively in Fennel. * * @author Zelaine Fong * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelOnlyTupleReader.java#5 $ */ public class FennelOnlyTupleReader implements FennelTupleReader { //~ Instance fields -------------------------------------------------------- private final FennelTupleAccessor tupleAccessor; private final FennelTupleData tupleData; //~ Constructors ----------------------------------------------------------- /** * @param tupleDesc tuple descriptor of the tuples to be read * @param tupleData tuple data that the tuples read will be unmarshalled * into */ public FennelOnlyTupleReader( FennelTupleDescriptor tupleDesc, FennelTupleData tupleData) { tupleAccessor = new FennelTupleAccessor(true); tupleAccessor.compute(tupleDesc); this.tupleData = tupleData; } //~ Methods ---------------------------------------------------------------- // implement FennelTupleReader public Object unmarshalTuple( ByteBuffer byteBuffer, byte [] byteArray, ByteBuffer sliceBuffer) { if (tupleAccessor.getCurrentTupleBuf() == null) { tupleAccessor.setCurrentTupleBuf(byteBuffer); } tupleAccessor.unmarshal(tupleData); return tupleData; } } // End FennelOnlyTupleReader.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoTransform.java0000444000175000017500000000770211173714170026174 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoTransform.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; /** * A piece of generated code must implement this interface if it is to be * callable from a Fennel JavaTransformExecStream wrapper. See {@link * net.sf.farrago.query.FarragoTransformDef}, which manages the construction of * a FarragoTransform during statement preparation, in {@link * net.sf.farrago.query.FarragoPreparingStmt}. * * @author Julian Hyde, Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoTransform.java#11 $ */ public interface FarragoTransform { //~ Methods ---------------------------------------------------------------- /** * Binds all inputs and initializes the transform. This method is typically * generated. It is called by {@link * net.sf.farrago.query.FarragoExecutableJavaStmt#execute}. * * @param connection the FarragoRuntimeContext of the query that contains * this transform. * @param farragoTransformStreamName the globally unique name of the * ExecStream that implements this transform. * @param inputBindings bindings between the transform's input streamIds and * the ordinal assigned to them in the stream graph */ void init( FarragoRuntimeContext connection, String farragoTransformStreamName, InputBinding [] inputBindings); /** * Does a quantum of work. Called by Fennel's JavaTransformExecStream. * * @param outputBuffer output ByteBuffer into which tuples are marshaled * @param quantum the maximum number of tuples that should be processed * before returning (in practice this is limited to 2^32) * * @return bytes marshalled into outputBuffer; 0 means end of stream, less * than 0 indicates an input underflow */ int execute(ByteBuffer outputBuffer, long quantum); /** * Sets a timeout for fetching an input row. 0 means poll, infinity (ie * Long.MAX_VALUE) means block. The default is to block; */ void setInputFetchTimeout(long millisecs); /** * Restarts this transform's underlying TupleIter(s). */ void restart(); //~ Inner Classes ---------------------------------------------------------- /** * InputBinding binds a JavaTransformExecStream input's streamId to the * ordinal assigned to that input by the stream graph. The InputBinding * objects are created by {@link * net.sf.farrago.query.FarragoTransformDef#init}. */ public static class InputBinding { private final String inputStreamName; private final int ordinal; public InputBinding(String inputStreamName, int ordinal) { this.inputStreamName = inputStreamName; this.ordinal = ordinal; } public String getInputStreamName() { return inputStreamName; } public int getOrdinal() { return ordinal; } } } // End FarragoTransform.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/package.html0000444000175000017500000000133411173714170024330 0ustar drazzibdrazzib Package net.sf.farrago.runtime Provides runtime support for Farrago query execution.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/runtime/package.html#8 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi

Query execution code generated by classes in {@link net.sf.farrago.query} references classes defined in this package. See also {@link net.sf.farrago.type.runtime}. eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoGeneratedCodeExamples.java0000444000175000017500000001153211173714170030405 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoGeneratedCodeExamples.java#12 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; /** * Sandbox for experiments in code generation. * *

THIS IS NOT A TEST! (Well not as such.) * *

This code fragments in this class serves two purposes: * *

    *
  • As an example of the code produced by a code-generator (cross-referenced * by javadoc comments in the code-generator); and
  • *
  • To help analyse the impact of changing runtime data structures. Suppose * we were to rename the {@link * FarragoRuntimeContext#newFennelTransformTupleIter} method. Then the {@link * #exampleFarragoTransform()} method would fail to compile. We can find the * generator of this code by finding all javadoc references to the {@link * #exampleFarragoTransform()} method. *
* * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoGeneratedCodeExamples.java#12 $ */ public class FarragoGeneratedCodeExamples { //~ Methods ---------------------------------------------------------------- public void exampleFarragoTransform() { FarragoRuntimeContext connection = null; ByteBuffer outputBuffer = ByteBuffer.allocate(1); String farragoTransformStreamName = "JavaTransformExecStream global name"; FarragoTransform.InputBinding [] inputBindings = new FarragoTransform.InputBinding[] { new FarragoTransform.InputBinding("SomeExecStream#1:100", 0), }; // Constructed by JavaTransformExecStream FarragoTransform transform = new ExampleGeneratedFarragoTransform(); // To initialize, JavaTransformExecStream calls: transform.init(connection, farragoTransformStreamName, inputBindings); // then to perform work it repeatedly calls: transform.execute(outputBuffer, 1000); } //~ Inner Classes ---------------------------------------------------------- /** * ExampleGeneratedFarragoTransform an example of what a generated * FarragoTransform looks like. See {@link * FarragoGeneratedCodeExamples#exampleFarragoTransform()}. */ public class ExampleGeneratedFarragoTransform extends FarragoTransformImpl implements FarragoTransform { public void init( FarragoRuntimeContext connection, String farragoTransformStreamName, FarragoTransform.InputBinding [] inputBindings) { super.init( // tuple writer generated by IteratorToFennelConverter new FennelTupleWriter() { protected void marshalTupleOrThrow( ByteBuffer sliceBuffer, Object object) { // ... } }, // To do any actual work, this TupleIter is wrapped in // another TupleIter, such as a CalcTupleIter, // generated by one or more JavaRels. There may be // multiple newFennelTransformTupleIter calls and an // iterator-based join here. connection.newFennelTransformTupleIter( // tuple reader generated by FennelToIteratorConverter new FennelTupleReader() { public Object unmarshalTuple( ByteBuffer byteBuffer, byte [] byteArray, ByteBuffer sliceBuffer) { return null; } }, farragoTransformStreamName, "SomeExecStream#1:100", // the input ExecStream's name inputBindings, null)); } } } // End FarragoGeneratedCodeExamples.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelTupleIter.java0000444000175000017500000000753611173714170025771 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTupleIter.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import net.sf.farrago.fennel.*; /** * FennelTupleIter implements the {@link org.eigenbase.runtime.TupleIter} * interfaces by reading tuples from a Fennel ExecStream. * *

FennelTupleIter only deals with raw byte buffers; it delegates to a {@link * FennelTupleReader} object the responsibility to unmarshal individual fields. * *

FennelTupleIter's implementation of {@link #populateBuffer()} blocks. * * @author John V. Sichi, Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTupleIter.java#7 $ */ public class FennelTupleIter extends FennelAbstractTupleIter { //~ Instance fields -------------------------------------------------------- private final FennelStreamGraph streamGraph; private final FennelStreamHandle streamHandle; //~ Constructors ----------------------------------------------------------- /** * Creates a new FennelTupleIter object. * * @param tupleReader FennelTupleReader to use to interpret Fennel data * @param streamGraph underlying FennelStreamGraph * @param streamHandle handle to underlying Fennel ExecStream that this * TupleIter reads from * @param bufferSize number of bytes in buffer used for fetching from Fennel */ public FennelTupleIter( FennelTupleReader tupleReader, FennelStreamGraph streamGraph, FennelStreamHandle streamHandle, int bufferSize) { super(tupleReader); this.streamGraph = streamGraph; this.streamHandle = streamHandle; // In this implementation of FennelAbstractTupleIter, byteBuffer and // bufferAsArray are effectively final. In other implementations, they // might be set by populateBuffer. bufferAsArray = new byte[bufferSize]; byteBuffer = ByteBuffer.wrap(bufferAsArray); byteBuffer.order(ByteOrder.nativeOrder()); byteBuffer.clear(); byteBuffer.limit(0); } //~ Methods ---------------------------------------------------------------- // override FennelAbstractTupleIter public void restart() { super.restart(); bufferAsArray = byteBuffer.array(); byteBuffer.clear(); byteBuffer.limit(0); streamGraph.restart(streamHandle); } // implement TupleIter public void closeAllocation() { // REVIEW: SWZ: 2/23/2006: Deallocate byteBuffer here? } /** * Blocking implementation of {@link FennelTupleIter#populateBuffer()}. * * @return number of bytes read into {@link FennelTupleIter#byteBuffer} or 0 * for end of stream. */ protected int populateBuffer() { byteBuffer.clear(); return streamGraph.fetch(streamHandle, bufferAsArray); } } // End FennelTupleIter.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/NativeRuntimeContext.java0000444000175000017500000001522411173714170027054 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/NativeRuntimeContext.java#6 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import java.sql.*; import java.util.*; import java.util.logging.*; import net.sf.farrago.fennel.*; import net.sf.farrago.fennel.tuple.*; import net.sf.farrago.type.*; import org.eigenbase.reltype.*; import org.eigenbase.sql.type.*; import org.eigenbase.trace.*; import org.eigenbase.util.*; /** * NativeRuntimeContext integrates Fennel with FarragoRuntimeContext. Currently, * it supports Fennel errors. * * @author John Pham * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/NativeRuntimeContext.java#6 $ */ class NativeRuntimeContext { //~ Static fields/initializers --------------------------------------------- /** * ErrorLevel. Keep this consistent with fennel/exec/ErrorTarget.h */ public static final int ROW_ERROR = 1000; public static final int ROW_WARNING = 500; //~ Instance fields -------------------------------------------------------- private FarragoRuntimeContext context; private Map streamMap; //~ Constructors ----------------------------------------------------------- /** * Creates a new NativeRuntimeContext instance as a wrapper around a * FarragoRuntimeContext. */ public NativeRuntimeContext(FarragoRuntimeContext context) { this.context = context; streamMap = new HashMap(); } //~ Methods ---------------------------------------------------------------- /** * Handles a Fennel row exception by converting Fennel data into Farrago * data. Delegates to {@link StreamDescriptor}. * * @see FennelJavaErrorTarget#handleRowError for a description of the * parameters */ public Object handleRowError( String source, boolean isWarning, String msg, ByteBuffer byteBuffer, int index) { StreamDescriptor streamDesc = streamMap.get(source); if (streamDesc == null) { streamDesc = new StreamDescriptor(context, source); streamMap.put(source, streamDesc); } byteBuffer.order(ByteOrder.nativeOrder()); return streamDesc.postError(isWarning, msg, byteBuffer, index); } //~ Inner Classes ---------------------------------------------------------- /** * StreamDescriptor represents a unique Fennel error source. Each instance * has it's own error tag and record format. */ private class StreamDescriptor { private final FarragoRuntimeContext runtimeContext; private final String tag; private final FennelTupleData tupleData; private final FennelTupleAccessor tupleAccessor; private final String [] columnNames; private final Object [] columnValues; private final ResultSetMetaData metadata; /** * Constructs a StreamDescriptor * * @param runtimeContext reference to the runtime context * @param source name of the Fennel error source */ public StreamDescriptor( FarragoRuntimeContext runtimeContext, String source) { this.runtimeContext = runtimeContext; this.tag = source + "_" + Util.getFileTimestamp(); RelDataType rowType = runtimeContext.getRowTypeForResultSet(source); if (rowType == null) { tupleData = null; tupleAccessor = null; metadata = null; columnNames = null; columnValues = null; return; } FennelTupleDescriptor tupleDesc = FennelUtil.convertRowTypeToFennelTupleDesc(rowType); tupleData = new FennelTupleData(tupleDesc); tupleAccessor = new FennelTupleAccessor(true); tupleAccessor.compute(tupleDesc); metadata = new FarragoResultSetMetaData(rowType); columnNames = SqlTypeUtil.getFieldNames(rowType); columnValues = new Object[columnNames.length]; } /** * Builds an error record and posts an error with the runtime context * * @see FennelJavaErrorTarget#handleRowError for a description of the * parameters */ public Object postError( boolean isWarning, String msg, ByteBuffer byteBuffer, int index) { // decoding Fennel data requires metadata if (metadata == null) { EigenbaseTrace.getStatementTracer().log( Level.WARNING, "failed to get metadata for '" + tag + "'"); return null; } tupleAccessor.setCurrentTupleBuf(byteBuffer); tupleAccessor.unmarshal(tupleData); try { for (int i = 0; i < columnValues.length; i++) { // Note: result sets are 1-indexed columnValues[i] = FennelTupleResultSet.getRawColumnData( i + 1, metadata, tupleData); } } catch (SQLException ex) { EigenbaseTrace.getStatementTracer().log( Level.WARNING, "failed to get raw column data", ex); return null; } return runtimeContext.handleRowError( columnNames, columnValues, new EigenbaseException(msg, null), index, tag, isWarning); } } } // End NativeRuntimeContext.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoUdrInvocationFrame.java0000444000175000017500000000325611173714170027760 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoUdrInvocationFrame.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.sql.*; import net.sf.farrago.session.*; import org.eigenbase.enki.mdr.*; /** * FarragoUdrInvocationFrame represents one entry on the routine invocation * stack for a given thread. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoUdrInvocationFrame.java#8 $ */ class FarragoUdrInvocationFrame { //~ Instance fields -------------------------------------------------------- FarragoRuntimeContext context; EnkiMDSession reposSession; FarragoSessionUdrContext udrContext; boolean allowSql; Connection connection; } // End FarragoUdrInvocationFrame.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelAbstractTupleIter.java0000444000175000017500000001377611173714170027460 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelAbstractTupleIter.java#8 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import net.sf.farrago.fennel.tuple.*; import org.eigenbase.runtime.*; /** * FennelAbstractTupleIter implements the {@link TupleIter} interface by * unmarshalling Fennel tuples from a buffer. * *

FennelAbstractTupleIter only deals with raw byte buffers; it is the * responsibility of the contained {@link FennelTupleReader} object to unmarshal * individual fields. * *

Neither does it actually populate the source buffer. This is the * responsibility of the {@link #populateBuffer()} method, which must be * implemented by the subclass. The subclass may optionally override the {@link * #requestData()} method to tell the producer that it is safe to start * producing more data. * * @author John V. Sichi, Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelAbstractTupleIter.java#8 $ */ public abstract class FennelAbstractTupleIter extends AbstractTupleIter { //~ Static fields/initializers --------------------------------------------- /** * Singleton helper for aligning tuple buffers correctly. */ private static FennelTupleAccessor tupleAligner = new FennelTupleAccessor(); //~ Instance fields -------------------------------------------------------- protected final FennelTupleReader tupleReader; protected ByteBuffer byteBuffer; protected byte [] bufferAsArray; private boolean endOfData; //~ Constructors ----------------------------------------------------------- /** * Creates a new FennelAbstractTupleIter object. * * @param tupleReader FennelTupleReader to use to interpret Fennel data */ public FennelAbstractTupleIter(FennelTupleReader tupleReader) { this.tupleReader = tupleReader; this.endOfData = false; } //~ Methods ---------------------------------------------------------------- /** * For subclasses that trace, returns a terse description of the status. * * @param prefix prepended to the results */ protected String getStatus(String prefix) { StringBuffer sb = new StringBuffer(prefix); if (prefix.length() > 0) { sb.append(" "); } if (byteBuffer == null) { sb.append("buf: null"); } else { sb.append("buf: ").append( Integer.toHexString(byteBuffer.hashCode())); sb.append(" (").append(byteBuffer).append(")"); } if (endOfData) { sb.append(" EOD"); } return sb.toString(); } // implement TupleIter public void restart() { this.endOfData = false; } // implement TupleIter // Note that we hold the buffer whenever this returns something other // than NoDataReason. public Object fetchNext() { if (endOfData) { return NoDataReason.END_OF_DATA; } else if (byteBuffer.hasRemaining()) { return unmarshal(); } int cb = populateBuffer(); if (cb == 0) { bufferAsArray = null; endOfData = true; return NoDataReason.END_OF_DATA; } else if (cb < 0) { return NoDataReason.UNDERFLOW; } byteBuffer.limit(cb); return unmarshal(); } private Object unmarshal() { // REVIEW: is slice allocation worth it? ByteBuffer sliceBuffer = byteBuffer.slice(); sliceBuffer.order(byteBuffer.order()); Object obj = tupleReader.unmarshalTuple(byteBuffer, bufferAsArray, sliceBuffer); int newPosition = byteBuffer.position() + sliceBuffer.position(); // eat final alignment padding newPosition = tupleAligner.alignRoundUp(newPosition); byteBuffer.position(newPosition); traceNext(obj); if (!byteBuffer.hasRemaining()) { requestData(); } return obj; } // override to trace the buffer state after unmarshal(), but before refill protected void traceNext(Object val) { } /** * Populates the buffer with a new batch of data, and returns the size in * bytes. The buffer position is set to the start. The call may block until * the buffer is filled or it may return an indication that there is no data * currently available. A subclass can implement this to fill the buffer * itself, or it can work by allowing an outside object to fill the buffer. * * @return The number of bytes now in the buffer. 0 means end of stream. * Less than 0 means no data currently available. */ protected abstract int populateBuffer(); /** * This method is called when the contents of the buffer have been consumed. * A subclass may use this method to tell the producer that it can start * producing. The default implementation does nothing. The method should not * block. */ protected void requestData() { } } // End FennelAbstractTupleIter.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoJavaUdxIterator.java0000444000175000017500000004113011173714170027266 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoJavaUdxIterator.java#22 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.lang.reflect.*; import java.math.*; import java.sql.*; import java.util.*; import java.util.concurrent.*; import java.util.logging.*; import net.sf.farrago.jdbc.param.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; import net.sf.farrago.type.*; import net.sf.farrago.type.runtime.*; import org.eigenbase.reltype.*; import org.eigenbase.runtime.*; import org.eigenbase.util.*; /** * FarragoJavaUdxIterator provides runtime support for a call to a Java UDX. It * supports both the blocking interface {@link Iterator} and the non-blocking * {@link TupleIter}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoJavaUdxIterator.java#22 $ */ public abstract class FarragoJavaUdxIterator extends ThreadIterator implements RestartableIterator, TupleIter { //~ Static fields/initializers --------------------------------------------- private static final int QUEUE_ARRAY_SIZE = 100; protected static final Logger tracer = FarragoTrace.getRuntimeContextTracer(); //~ Instance fields -------------------------------------------------------- private final FarragoSyntheticObject [] rowObjs; private final PreparedStatement resultInserter; // protected because needed by generated subclasses protected final FarragoSessionRuntimeContext runtimeContext; private int iRow; private long defaultTimeout = Long.MAX_VALUE; private boolean timeoutAsUnderflow = true; private boolean stopThread; private CountDownLatch latch; private final ParameterMetaData parameterMetaData; private List restartableInputs; //~ Constructors ----------------------------------------------------------- protected FarragoJavaUdxIterator( FarragoSessionRuntimeContext runtimeContext, Class rowClass, RelDataType rowType) { super(new ArrayBlockingQueue(QUEUE_ARRAY_SIZE)); this.runtimeContext = runtimeContext; runtimeContext.addAllocation(this); parameterMetaData = new FarragoParameterMetaData(rowType); // NOTE jvs 16-Jan-2006: We construct a circular array with two extra // slots: one for the producer thread to write into, and one for the // consumer thread to read from; this guarantees that we // never recycle a row still accessible by the consumer. rowObjs = new FarragoSyntheticObject[QUEUE_ARRAY_SIZE + 2]; try { for (int i = 0; i < rowObjs.length; ++i) { rowObjs[i] = (FarragoSyntheticObject) rowClass.newInstance(); } } catch (Throwable ex) { throw Util.newInternal(ex); } iRow = 0; resultInserter = (PreparedStatement) Proxy.newProxyInstance( null, new Class[] { PreparedStatement.class }, new PreparedStatementInvocationHandler(rowType)); restartableInputs = new ArrayList(); } //~ Methods ---------------------------------------------------------------- // override QueueIterator public boolean hasNext() { if (latch == null) { // NOTE: we don't actually start the thread until the first call to // hasNext, because first we need "this" to be fully constructed, // including subclasses; also the Fennel plan needs to be loaded. startWithLatch(); } return super.hasNext(); } // override QueueIterator public boolean hasNext(long timeout) throws QueueIterator.TimeoutException { if (latch == null) { startWithLatch(); } return super.hasNext(timeout); } // implement TupleIter public boolean setTimeout(long timeout, boolean asUnderflow) { this.defaultTimeout = timeout; this.timeoutAsUnderflow = asUnderflow; return true; } // implement TupleIter public Object fetchNext() { try { if (defaultTimeout < Long.MAX_VALUE) { return next(defaultTimeout); } else { return next(); } } catch (NoSuchElementException e) { return NoDataReason.END_OF_DATA; } catch (QueueIterator.TimeoutException e) { if (timeoutAsUnderflow) { return NoDataReason.UNDERFLOW; } else { throw new TupleIter.TimeoutException(); } } } /** * Called by generated code to add an input cursor's iterator so that it can * be restarted as needed. * * @param inputIter input cursor's iterator */ protected void addRestartableInput(TupleIter inputIter) { restartableInputs.add(inputIter); } // implement ThreadIterator protected void doWork() { // Start a repository session in the event that the UDX accesses the // metadata repository -- the session is lightweight, so no problem // if repository txn is never started try { runtimeContext.getSession().getRepos().beginReposSession(); try { executeUdx(); } finally { runtimeContext.getSession().getRepos().endReposSession(); } } finally { latch.countDown(); } } // NOTE: called from generated code public PreparedStatement getResultInserter() { return resultInserter; } public FarragoSyntheticObject getCurrentRow() { return rowObjs[iRow]; } // implement RestartableIterator public void restart() { stopWithLatch(); reset(1); // Nullify thread. onEndOfQueue(); // Toss anything it was producing. queue.clear(); // Input cursors are currently "throwaway", but this is still // needed so that we correctly invoke a restart on Fennel streams. for (TupleIter inputIter : restartableInputs) { inputIter.restart(); } restartableInputs.clear(); // Restart a new thread. startWithLatch(); } // implement TupleIter public void closeAllocation() { stopWithLatch(); } private void stopWithLatch() { if (latch == null) { // thread never ran return; } // Tell the running thread to buzz off. stopThread = true; try { // Wait for it to die. (TODO: If we ever get ThreadIterator // to stop using daemons, change this to use thread.join instead.) latch.await(); } catch (InterruptedException ex) { throw Util.newInternal(ex); } stopThread = false; } private void startWithLatch() { latch = new CountDownLatch(1); start(); } private void checkCancel() { runtimeContext.checkCancel(); if (stopThread) { throw new RuntimeException("UDX thread stop requested"); } } /** * Calls specific UDX to produce result set. Subclass implementation is * typically code-generated. */ protected abstract void executeUdx(); //~ Inner Classes ---------------------------------------------------------- public class PreparedStatementInvocationHandler extends BarfingInvocationHandler { private final FarragoJdbcParamDef [] dynamicParamDefs; PreparedStatementInvocationHandler(RelDataType paramRowType) { RelDataTypeField [] fields = paramRowType.getFields(); dynamicParamDefs = new FarragoJdbcParamDef[fields.length]; for (int i = 0; i < fields.length; ++i) { FarragoParamFieldMetaData paramMetaData = FarragoRuntimeJdbcUtil.newParamFieldMetaData( fields[i].getType(), ParameterMetaData.parameterModeIn); dynamicParamDefs[i] = FarragoJdbcParamDefFactory.instance.newParamDef( fields[i].getName(), paramMetaData, false); } } // implement PreparedStatement public int executeUpdate() throws SQLException { checkCancel(); // on a full pipe, timeout every second to check cancellation; we // have to do it this way because the iterator above us // may not get sucked dry when the cursor is closed, in which // case we'll be stuck on the full pipe unless we can check // for cancellation while (!offer( getCurrentRow(), 1000)) { checkCancel(); } ++iRow; if (iRow >= rowObjs.length) { iRow = 0; } return 1; } // implement PreparedStatement public ParameterMetaData getParameterMetaData() { return parameterMetaData; } // implement PreparedStatement public void clearParameters() throws SQLException { int n = getCurrentRow().getFields().length; for (int i = 0; i < n; ++i) { setDynamicParam(i + 1, null, null); } } private void setDynamicParam( int parameterIndex, Object obj, Calendar calendar) throws SQLException { int iField = parameterIndex - 1; // Result types are always nullable, so we should get something // which is both a NullableValue and an AssignableValue. However // SqlDateTimeWithoutTZ is not a NullableValue, for some reason. // Hack around this for the time being, as changing // SqlDateTimeWithoutTZ seems to cause unmarshalling problems. Object fieldObj = getCurrentRow().getFieldValue(iField); if (fieldObj instanceof NullableValue) { NullableValue nullableValue = (NullableValue) fieldObj; nullableValue.setNull(obj == null); } else if (fieldObj instanceof SqlDateTimeWithoutTZ) { SqlDateTimeWithoutTZ dt = (SqlDateTimeWithoutTZ) fieldObj; dt.setNull(obj == null); // its own public method! } if (obj != null) { AssignableValue assignableValue = (AssignableValue) fieldObj; // Note: Calendar is an optional argument so it wouldn't // make sense to pass in a null Calendar as a parameter Object scrubbedValue; if (calendar == null) { scrubbedValue = dynamicParamDefs[iField].scrubValue(obj); } else { scrubbedValue = dynamicParamDefs[iField].scrubValue(obj, calendar); } assignableValue.assignFrom(scrubbedValue); } } // implement PreparedStatement public void setNull( int parameterIndex, int sqlType) throws SQLException { setDynamicParam(parameterIndex, null, null); } // implement PreparedStatement public void setBoolean( int parameterIndex, boolean x) throws SQLException { setDynamicParam( parameterIndex, Boolean.valueOf(x), null); } // implement PreparedStatement public void setByte( int parameterIndex, byte x) throws SQLException { setDynamicParam( parameterIndex, new Byte(x), null); } // implement PreparedStatement public void setShort( int parameterIndex, short x) throws SQLException { setDynamicParam( parameterIndex, new Short(x), null); } // implement PreparedStatement public void setInt( int parameterIndex, int x) throws SQLException { setDynamicParam( parameterIndex, new Integer(x), null); } // implement PreparedStatement public void setLong( int parameterIndex, long x) throws SQLException { setDynamicParam( parameterIndex, new Long(x), null); } // implement PreparedStatement public void setFloat( int parameterIndex, float x) throws SQLException { setDynamicParam( parameterIndex, new Float(x), null); } // implement PreparedStatement public void setDouble( int parameterIndex, double x) throws SQLException { setDynamicParam( parameterIndex, new Double(x), null); } // implement PreparedStatement public void setBigDecimal( int parameterIndex, BigDecimal x) throws SQLException { setDynamicParam(parameterIndex, x, null); } // implement PreparedStatement public void setString( int parameterIndex, String x) throws SQLException { setDynamicParam(parameterIndex, x, null); } // implement PreparedStatement public void setBytes( int parameterIndex, byte [] x) throws SQLException { setDynamicParam(parameterIndex, x, null); } // implement PreparedStatement public void setDate( int parameterIndex, java.sql.Date x) throws SQLException { setDynamicParam(parameterIndex, x, null); } // implement PreparedStatement public void setDate( int parameterIndex, java.sql.Date x, Calendar c) throws SQLException { setDynamicParam(parameterIndex, x, c); } // implement PreparedStatement public void setTime( int parameterIndex, Time x) throws SQLException { setDynamicParam(parameterIndex, x, null); } // implement PreparedStatement public void setTime( int parameterIndex, Time x, Calendar c) throws SQLException { setDynamicParam(parameterIndex, x, c); } // implement PreparedStatement public void setTimestamp( int parameterIndex, Timestamp x) throws SQLException { setDynamicParam(parameterIndex, x, null); } // implement PreparedStatement public void setTimestamp( int parameterIndex, Timestamp x, Calendar c) throws SQLException { setDynamicParam(parameterIndex, x, c); } // implement PreparedStatement public void setObject( int parameterIndex, Object x) throws SQLException { setDynamicParam(parameterIndex, x, null); } } } // End FarragoJavaUdxIterator.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelPipeIterator.java0000444000175000017500000000675311173714170026463 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelPipeIterator.java#15 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.util.*; import java.util.logging.*; import org.eigenbase.runtime.*; /** * FennelPipeIterator implements the {@link RestartableIterator} interface, * receiving data from a producer as {@link java.nio.ByteBuffer} objects, and * unmarshalling them to a consumer. It does this by extending {@link * FennelPipeTupleIter} and adapting TupleIter semantics to Iterator semantics. * * @author Julian Hyde * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelPipeIterator.java#15 $ */ public class FennelPipeIterator extends FennelPipeTupleIter implements RestartableIterator { //~ Instance fields -------------------------------------------------------- private Object next = null; // current row //~ Constructors ----------------------------------------------------------- /** * creates a new FennelPipeIterator object. * * @param tupleReader FennelTupleReader to use to interpret Fennel data */ public FennelPipeIterator(FennelTupleReader tupleReader) { super(tupleReader); } //~ Methods ---------------------------------------------------------------- // implement Iterator public boolean hasNext() { if (next != null) { traceHasNext(true); return true; } Object fetched = fetchNext(); if (fetched == NoDataReason.END_OF_DATA) { traceHasNext(false); return false; } // Old-style iterator convention doesn't handle anything but // END_OF_DATA assert (!(fetched instanceof NoDataReason)); next = fetched; traceHasNext(true); return true; } private void traceHasNext(boolean hasNextResult) { if (!tracer.isLoggable(Level.FINE)) { return; } if (!hasNextResult || tracer.isLoggable(Level.FINER)) { String msg = getStatus(this.toString()) + " => " + hasNextResult; if (!hasNextResult) { tracer.fine(msg); } else { tracer.finer(msg); } } } // implement Iterator public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } Object result = next; next = null; return result; } // implement Iterator public void remove() { throw new UnsupportedOperationException(); } } // End FennelPipeIterator.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelPipeTupleIter.java0000444000175000017500000001615511173714170026604 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelPipeTupleIter.java#9 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import java.util.logging.*; import net.sf.farrago.trace.*; import org.eigenbase.util.*; /** * FennelPipeTupleIter implements the {@link org.eigenbase.runtime.TupleIter} * interface, receiving data from a producer as {@link ByteBuffer} objects, and * unmarshalling them to a consumer. * *

A FennelPipeTupleIter has a C++ peer, a JavaSinkExecstream. The peer sends * marshalled data, wrapped as a ByteBuffer. The reader has a current buffer * from which it unmarshals rows on demand, and a queue of buffers to read next. * The queue is synchronized; but it is left available to the writer between * TupleIter calls (#fetchNext()). Otherwise, if it were unavailable for a long * time, the peer XO would block, which is a severe problem for a single-thread * XO scheduler. * * @author Julian Hyde, Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelPipeTupleIter.java#9 $ */ public class FennelPipeTupleIter extends FennelAbstractTupleIter { //~ Static fields/initializers --------------------------------------------- protected static final Logger tracer = FarragoTrace.getFennelPipeIteratorTracer(); //~ Instance fields -------------------------------------------------------- // byteBuffer is the current buffer, and belongs exclusively to the reader // (this object) /** * buffers from the writer, not yet read */ private final ArrayQueue moreBuffers; //~ Constructors ----------------------------------------------------------- /** * creates a new FennelPipeTupleIter object. * * @param tupleReader FennelTupleReader to use to interpret Fennel data */ public FennelPipeTupleIter(FennelTupleReader tupleReader) { super(tupleReader); // start with an empty buffer queue moreBuffers = new ArrayQueue(2); // Create an empty byteBuffer which will cause us to fetch new rows the // first time our consumer tries to fetch. TODO: Add a new state 'have // not yet checked whether we have more data'. bufferAsArray = new byte[0]; byteBuffer = ByteBuffer.wrap(bufferAsArray); byteBuffer.clear(); byteBuffer.limit(0); } //~ Methods ---------------------------------------------------------------- /** * adds a buffer to the buffer queue. The writer peer calls this. */ private void enqueue(ByteBuffer bb) { synchronized (moreBuffers) { moreBuffers.offer(bb); if (moreBuffers.size() == 1) { // was empty moreBuffers.notify(); // REVIEW mb: Use Semaphore instead? } } } /** * Gets the head buffer from the queue. If the queue is empty, blocks until * a buffer arrives. */ private ByteBuffer dequeue() { Object head = null; synchronized (moreBuffers) { head = moreBuffers.poll(); while (head == null) { try { moreBuffers.wait(); } catch (InterruptedException e) { } head = moreBuffers.poll(); } } return (ByteBuffer) head; } // override FennelAbstractTupleIter to trace public void restart() { tracer.fine(this.toString()); super.restart(); } // override FennelAbstractTupleIter protected void traceNext(Object val) { if (tracer.isLoggable(Level.FINER)) { tracer.finer(getStatus(this.toString()) + " => " + val); } } // implement TupleIter public void closeAllocation() { // REVIEW: SWZ: 2/23/2006: Deallocate byteBuffer here? } protected int populateBuffer() { tracer.fine(this + " reader waits"); byteBuffer = dequeue(); // get next buffer; may block int n = byteBuffer.limit(); if (n > 0) { bufferAsArray = byteBuffer.array(); } if (tracer.isLoggable(Level.FINE)) { tracer.fine(getStatus(this.toString()) + " => " + n); } return n; } /** * Gets a direct ByteBuffer suitable for #write. The C++ caller may pin the * backing array (JNI GetByteArrayElements), copy data, and then pass back * the ByteBuffer by calling #write. */ public ByteBuffer getByteBuffer(int size) { // REVIEW mb 8/22/05 Why not call ByteBuffer.allocateDirect(size) ? // Why can't C++ peer call it directly? // Or else recycle buffer with a free list. byte [] b = new byte[size]; ByteBuffer bb = ByteBuffer.wrap(b); bb.order(ByteOrder.nativeOrder()); bb.clear(); return bb; } /** * Writes the contents of a byte buffer into this iterator. To avoid an * extra copy here, the buffer should be direct and expose its backing array * (ie byteBufer.hasArray() == true). (Unfortunately the result * of JNI NewDirectByteBuffer() need not have a backing array). * *

This method is called by the producer, typically from JNI. * *

The limit of the byte buffer is ignored; the bblen * parameter is used instead. * * @param bb A ByteBuffer containing the new data * @param bblen size of {@code bb} in bytes; 0 means end of data. */ public void write(ByteBuffer bb, int bblen) throws Throwable { try { bb.limit(bblen); bb.position(0); if (!bb.hasArray()) { // argh, have to wrap a copy of the new data tracer.fine("copies buffer"); byte [] b = new byte[bblen]; bb.rewind(); bb.get(b); bb = ByteBuffer.wrap(b); } tracer.fine( this + " writer waits (buf: " + bb + " bytes: " + bblen); enqueue(bb); tracer.fine(this + " writer proceeds"); } catch (Throwable e) { tracer.throwing(null, null, e); throw e; } } } // End FennelPipeTupleIter.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoRuntimeContext.java0000444000175000017500000012252611173714170027213 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoRuntimeContext.java#90 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2003-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import java.sql.*; import java.sql.Date; import java.util.*; import java.util.logging.*; import javax.jmi.reflect.*; import net.sf.farrago.catalog.*; import net.sf.farrago.fem.fennel.*; import net.sf.farrago.fem.med.*; import net.sf.farrago.fennel.*; import net.sf.farrago.namespace.*; import net.sf.farrago.namespace.util.*; import net.sf.farrago.plugin.*; import net.sf.farrago.resource.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; import net.sf.farrago.type.runtime.*; import net.sf.farrago.util.*; import org.eigenbase.enki.mdr.*; import org.eigenbase.jmi.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.runtime.*; import org.eigenbase.trace.*; import org.eigenbase.util.*; /** * FarragoRuntimeContext defines runtime support routines needed by generated * code. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoRuntimeContext.java#90 $ */ public class FarragoRuntimeContext extends FarragoCompoundAllocation implements FarragoSessionRuntimeContext, RelOptConnection, FennelJavaStreamMap, FennelJavaErrorTarget { //~ Static fields/initializers --------------------------------------------- protected static final Logger tracer = FarragoTrace.getRuntimeContextTracer(); private static final ThreadLocal> threadInvocationStack = new ThreadLocal>(); //~ Instance fields -------------------------------------------------------- private final FarragoSession session; private final FarragoRepos repos; protected final FarragoObjectCache codeCache; private final Map txnCodeCache; private final FennelTxnContext fennelTxnContext; private final FarragoWarningQueue warningQueue; protected final Object cursorMonitor; private boolean cursorActive; private FennelExecutionHandle execHandle; /** * Maps stream id to the corresponding java object. */ private final Map streamIdToHandleMap = new HashMap(); // Maps FarragoTransform instances by their subclass names. private final Map transformMap = new HashMap(); protected final Object [] dynamicParamValues; protected FennelStreamGraph streamGraph; /** * responsible for closing the FennelStreamGraph */ protected final FarragoCompoundAllocation streamOwner; private final FarragoSessionIndexMap indexMap; private final FarragoSessionVariables sessionVariables; private final FarragoDataWrapperCache dataWrapperCache; private final FarragoStreamFactoryProvider streamFactoryProvider; private final boolean isDml; private long currentTime; private boolean isCanceled; protected boolean isClosed; private ClassLoader statementClassLoader; protected Map resultSetTypeMap; protected long stmtId; private NativeRuntimeContext nativeContext; private EnkiMDSession detachedSession; //~ Constructors ----------------------------------------------------------- /** * Creates a new FarragoRuntimeContext. * * @param params constructor params */ public FarragoRuntimeContext(FarragoSessionRuntimeParams params) { this.session = params.session; this.repos = params.repos; this.codeCache = params.codeCache; this.txnCodeCache = params.txnCodeCache; this.fennelTxnContext = params.fennelTxnContext; this.indexMap = params.indexMap; this.dynamicParamValues = params.dynamicParamValues; this.sessionVariables = params.sessionVariables; this.streamFactoryProvider = params.streamFactoryProvider; this.isDml = params.isDml; this.resultSetTypeMap = params.resultSetTypeMap; this.stmtId = params.stmtId; this.currentTime = params.currentTime; if (params.warningQueue == null) { params.warningQueue = new FarragoWarningQueue(); } this.warningQueue = params.warningQueue; cursorMonitor = new Object(); FarragoPluginClassLoader classLoader; if (session != null) { classLoader = session.getPluginClassLoader(); } else { statementClassLoader = classLoader = params.pluginClassLoader; } dataWrapperCache = new FarragoDataWrapperCache( this, params.sharedDataWrapperCache, classLoader, params.repos, params.fennelTxnContext.getFennelDbHandle(), (session != null) ? new FarragoSessionDataSource(session) : null); streamOwner = new StreamOwner(); } //~ Methods ---------------------------------------------------------------- // implement FarragoSessionRuntimeContext public FarragoWarningQueue getWarningQueue() { return warningQueue; } /** * Returns the stream graph. */ protected FennelStreamGraph getStreamGraph() { return streamGraph; } // implement RelOptConnection public RelOptSchema getRelOptSchema() { throw new AssertionError(); } // override CompoundClosableAllocation public synchronized void closeAllocation() { tracer.fine("closing allocation " + isClosed); if (isClosed) { return; } isClosed = true; isCanceled = true; boolean streamGraphClosed = false; // Override CompoundClosableAllocation behavior, because we // need special synchronization to account for the fact // that FarragoJavaUdxIterator instances may be adding themselves // concurrently during this shutdown. Question: is it possible // for one to leak due to a race? for (;;) { ClosableAllocation allocation; synchronized (allocations) { if (allocations.isEmpty()) { break; } allocation = allocations.remove(allocations.size() - 1); } if (allocation instanceof FarragoObjectCache.Entry) { Object cachedObj = ((FarragoObjectCache.Entry) allocation).getValue(); if (cachedObj == streamGraph) { // REVIEW jvs 1-Sep-2008: This is really gross. We're // between a rock (FRG-251) and a hard place (FRG-331). This // (FRG-338) is the temporary resolution, but we really need // to straighten out the UDX thread lifecycle once and for // all. assert (!streamGraphClosed); streamGraphClosed = true; closeStreamGraph(); } } allocation.closeAllocation(); } if (!streamGraphClosed) { // For txnCodeCache != null, or for a pure-Java statement, we // haven't actually unpinned any stream graph cache entry, but we // still have some cleanup to do. closeStreamGraph(); } if (detachedSession != null) { EnkiMDRepository mdrepos = getRepos().getEnkiMdrRepos(); EnkiMDSession callerSession = mdrepos.detachSession(); reattachMdrSession(); getRepos().endReposSession(); if (callerSession != null) { mdrepos.reattachSession(callerSession); } } } private void closeStreamGraph() { // make sure all streams get closed BEFORE they are deallocated streamOwner.closeAllocation(); if (!isDml) { // For queries, this is called when the cursor is closed. if (session != null) { session.endTransactionIfAuto(true); } } statementClassLoader = null; // FRG-253: nullify this, so that once we release its pinned entry from // the cache, we don't try to abort it after someone else starts to // reuse it! streamGraph = null; } // override CompoundClosableAllocation public void addAllocation(ClosableAllocation allocation) { synchronized (allocations) { super.addAllocation(allocation); } } // override CompoundClosableAllocation public boolean forgetAllocation(ClosableAllocation allocation) { synchronized (allocations) { return super.forgetAllocation(allocation); } } // override CompoundClosableAllocation public boolean hasAllocations() { synchronized (allocations) { return !allocations.isEmpty(); } } // implement RelOptConnection public Object contentsAsArray( String qualifier, String tableName) { throw new AssertionError(); } /** * Gets an object needed to support the implementation of foreign data * access. * * @param serverMofId MOFID of foreign server being accessed * @param param server-specific runtime parameter * * @return server-specific runtime support object */ public Object getDataServerRuntimeSupport( String serverMofId, Object param) { EnkiMDRepository mdrRepos = repos.getEnkiMdrRepos(); mdrRepos.beginSession(); mdrRepos.beginTrans(false); FarragoMedDataServer server; try { FemDataServer femServer = (FemDataServer) mdrRepos.getByMofId(serverMofId); server = dataWrapperCache.loadServerFromCatalog(femServer); } finally { mdrRepos.endTrans(); mdrRepos.endSession(); } try { Object obj = server.getRuntimeSupport(param); if (obj instanceof FarragoAllocation) { addAllocation((FarragoAllocation) obj); } return obj; } catch (Throwable ex) { throw FarragoResource.instance().DataServerRuntimeFailed.ex(ex); } } /** * Gets the MofId for a RefBaseObject, or null if the object is null. This * is called at execution from code generated by MdrTable. * * @param refObj RefBaseObject for which to get the MofId * * @return MofId or null */ public String getRefMofId(RefBaseObject refObj) { if (refObj == null) { return null; } else { return refObj.refMofId(); } } /** * Gets the value bound to a dynamic parameter. * * @param paramIndex 0-based index of parameter * * @return bound value */ public Object getDynamicParamValue(int paramIndex) { return dynamicParamValues[paramIndex]; } /** * Called from generated code. * * @return the value of context variable USER. */ public String getContextVariable_USER() { return sessionVariables.currentUserName; } /** * Called from generated code. * * @return the value of context variable CURRENT_USER. */ public String getContextVariable_CURRENT_USER() { return sessionVariables.currentUserName; } /** * Called from generated code. * * @return the value of context variable SYSTEM_USER. */ public String getContextVariable_SYSTEM_USER() { return sessionVariables.systemUserName; } /** * Called from generated code. * * @return the value of context variable SESSION_USER. */ public String getContextVariable_SESSION_USER() { return sessionVariables.sessionUserName; } /** * Called from generated code. * * @return the value of context variable CURRENT_ROLE. */ public String getContextVariable_CURRENT_ROLE() { return sessionVariables.currentRoleName; } /** * Called from generated code. * * @return the value of context variable CURRENT_CATALOG. */ public String getContextVariable_CURRENT_CATALOG() { return sessionVariables.catalogName; } /** * Called from generated code. * * @return the value of context variable CURRENT_SCHEMA. */ public String getContextVariable_CURRENT_SCHEMA() { // NOTE jvs 9-Mar-2009: SQL:2008 Part 2 Section 4.37.2 says the value // for CURRENT_SCHEMA when no schema has been set is // implementation-defined, so we use empty string since NULL // values aren't supported for context variables. return (sessionVariables.schemaName == null) ? "" : sessionVariables.schemaName; } /** * Called from generated code. * * @return the value of context variable CURRENT_PATH. * * @sql.99 Part 2 Section 6.3 General Rule 10 */ public String getContextVariable_CURRENT_PATH() { return sessionVariables.getFormattedSchemaSearchPath( session.getDatabaseMetaData()); } protected long getCurrentTime() { // NOTE jvs 25-Sept-2004: per SQL standard, the same time // is used for all references within the same statement. if (currentTime == 0) { // internally, we use a psuedo local time currentTime = System.currentTimeMillis(); } return currentTime; } /** * Called from generated code. * * @return the value of context variable CURRENT_DATE. */ public Date getContextVariable_CURRENT_DATE() { return new Date(getCurrentTime()); } /** * Called from generated code. * * @return the value of context variable CURRENT_TIME. */ public Time getContextVariable_CURRENT_TIME() { // Strip off the milliseconds in the time value since CURRENT_TIME // doesn't return that portion of the time long currTime = getCurrentTime(); return new Time(currTime - (currTime % 1000)); } /** * Called from generated code. * * @return the value of context variable CURRENT_TIMESTAMP. */ public Timestamp getContextVariable_CURRENT_TIMESTAMP() { return new Timestamp(getCurrentTime()); } /** * Called from generated code. * * @return the value of context variable LOCALTIME. */ public Time getContextVariable_LOCALTIME() { return getContextVariable_CURRENT_TIME(); } /** * Called from generated code. * * @return the value of context variable LOCALTIMESTAMP. */ public Timestamp getContextVariable_LOCALTIMESTAMP() { return getContextVariable_CURRENT_TIMESTAMP(); } // REVIEW jvs 22-Mar-2006: JavaPullTupleStream is no longer // used within Farrago, since everything is handled via transforms // instead. Is it still used outside of Farrago? /** * Associates a stream id with a java stream object, so that it can be * retrieved by a native method later. */ protected void registerJavaStream(int streamId, Object stream) { registerJavaStream(streamId, stream, this); } /** * Associates a stream id with a java stream object, so that it can be * retrieved by a native method later. Binds the stream to a specific owner * (that will eventually close it). */ protected void registerJavaStream( int streamId, Object stream, FarragoCompoundAllocation owner) { if (streamIdToHandleMap.containsKey(streamId)) { // or assert? tracer.warning( "replacing java peer for " + streamId + "; was " + streamIdToHandleMap.get(streamId) + " now is " + stream); } streamIdToHandleMap.put( streamId, FennelDbHandleImpl.allocateNewObjectHandle(owner, stream)); } /** * Associates a FarragoTransform instance with its class name, so that it * can be retrieved by a native method later. Binds the stream to a specific * owner (that will eventually close it). */ public void registerFarragoTransform(String key, FarragoTransform xform) { transformMap.put(key, xform); } public FarragoTransform findFarragoTransform(String key) { return transformMap.get(key); } /** * Stupid helper for code generated by {@link * net.sf.farrago.fennel.rel.FennelDoubleRel}. * * @param dummy1 a dummy * @param dummy2 another dummy * * @return yet another dummy */ public Object dummyPair( Object dummy1, Object dummy2) { assert (dummy1 == null); assert (dummy2 == null); return null; } /** * Stupid helper for code generated by {@link * net.sf.farrago.fennel.rel.FennelMultipleRel}. * * @param dummyArray array of dummies * * @return yet another dummy */ public Object dummyArray( Object [] dummyArray) { for (Object aDummyArray : dummyArray) { assert (aDummyArray == null); } return null; } // implement FarragoSessionRuntimeContext public void loadFennelPlan(final String xmiFennelPlan) { assert (streamGraph == null); FarragoObjectCache.CachedObjectFactory streamFactory = new FarragoObjectCache.CachedObjectFactory() { public void initializeEntry( Object key, FarragoObjectCache.UninitializedEntry entry) { assert (key.equals(xmiFennelPlan)); streamGraph = prepareStreamGraph(xmiFennelPlan); long memUsage = FarragoUtil.getFennelMemoryUsage(xmiFennelPlan); entry.initialize(streamGraph, memUsage, true); } public boolean isStale(Object value) { return false; } }; FarragoObjectCache.Entry cacheEntry = null; if (txnCodeCache != null) { cacheEntry = txnCodeCache.get(xmiFennelPlan); } if (cacheEntry == null) { cacheEntry = codeCache.pin(xmiFennelPlan, streamFactory, true); } if (txnCodeCache == null) { addAllocation(cacheEntry); } else { txnCodeCache.put(xmiFennelPlan, cacheEntry); } if (streamGraph == null) { streamGraph = (FennelStreamGraph) cacheEntry.getValue(); streamOwner.addAllocation(streamGraph); } } // implement FarragoSessionRuntimeContext public void openStreams() { assert (streamGraph != null); streamGraph.open(fennelTxnContext, this, this); } // implement FarragoSessionRuntimeContext public FennelStreamGraph getFennelStreamGraph() { return streamGraph; } /** * Creates a FennelTupleIter for executing a plan represented as XML. This * is called at execution from code generated by FennelToIteratorConverter. * The FennelTupleIter is registered as the java peer of streamId. * * @param tupleReader object providing FennelTupleReader implementation * @param streamName name of stream from which to read (globally unique) * @param streamId id of stream from which to read (unique within statement) * @param dummies a dummy parameter to give non-Fennel children a place to * generate code * * @return tuple iterator */ public TupleIter newFennelTupleIter( FennelTupleReader tupleReader, String streamName, int streamId, Object dummies) { assert (dummies == null); assert (streamGraph != null); FarragoReposTxnContext txn = repos.newTxnContext(true); txn.beginReadTxn(); try { FennelStreamHandle streamHandle = getStreamHandle(streamName, true); final FennelTupleIter iter = new FennelTupleIter( tupleReader, streamGraph, streamHandle, repos.getCurrentConfig().getFennelConfig() .getCachePageSize()); registerJavaStream(streamId, iter); return iter; } finally { txn.commit(); } } /** * Creates a FennelTupleIter for executing a plan represented as XML. This * iterator is used during execution in Fennel's JavaTransformExecStream * from code generated by FennelToIteratorConverter. * *

Note: The semantics of streamName and streamId differ from {@link * #newFennelTupleIter(FennelTupleReader, String, int, Object)}. The iter is * not registered as the java peer of the fennel stream; the registered peer * of the stream is instead the specially generated FarragoTransform. (See * {@link net.sf.farrago.query.FarragoTransformDef#init}.) * * @param tupleReader object providing FennelTupleReader implementation * @param streamName name of the JavaExecTransformStream we're reading on * behalf of * @param inputStreamName the global name of a stream to read * @param dummies a dummy parameter to give non-Fennel children a place to * generate code * * @return tuple iterator */ public TupleIter newFennelTransformTupleIter( FennelTupleReader tupleReader, String streamName, String inputStreamName, FarragoTransform.InputBinding [] inputBindings, Object dummies) { assert (dummies == null); assert (streamGraph != null); assert (inputBindings != null); FarragoReposTxnContext txn = repos.newTxnContext(true); txn.beginReadTxn(); try { FennelStreamHandle streamHandle = getStreamHandle(streamName, false); FennelStreamHandle inputStreamHandle = getStreamHandle(inputStreamName, true); FarragoTransform.InputBinding inputBinding = null; for (FarragoTransform.InputBinding binding : inputBindings) { // The binding's input stream name may be a buffer adapter // created to handle provisioning of buffers. It's name will // be the stream name we're looking for plus some additional // information. if (binding.getInputStreamName().startsWith(inputStreamName)) { inputBinding = binding; break; } } assert (inputBinding != null); return new FennelTransformTupleIter( tupleReader, streamGraph, streamHandle, inputStreamHandle, inputBinding.getOrdinal(), repos.getCurrentConfig().getFennelConfig().getCachePageSize()); } finally { txn.commit(); } } // implement FarragoSessionRuntimeContext public FennelStreamHandle getStreamHandle( String globalStreamName, boolean isInput) { return streamGraph.findStream(repos, globalStreamName, isInput); } protected FennelStreamGraph prepareStreamGraph(String xmiFennelPlan) { boolean success = false; FennelStreamGraph newStreamGraph = null; repos.beginReposSession(); try { Collection collection = JmiObjUtil.importFromXmiString( repos.getTransientFarragoPackage(), xmiFennelPlan); assert (collection.size() == 1); FemCmdPrepareExecutionStreamGraph cmd = (FemCmdPrepareExecutionStreamGraph) collection.iterator() .next(); newStreamGraph = fennelTxnContext.newStreamGraph(streamOwner); streamFactoryProvider.registerStreamFactories( newStreamGraph.getLongHandle()); cmd.setStreamGraphHandle(newStreamGraph.getStreamGraphHandle()); fennelTxnContext.getFennelDbHandle().executeCmd(cmd); success = true; return newStreamGraph; } catch (RuntimeException e) { // When these occur, it can cause the ensuing // FennelStorage.tupleStreamGraphClose() to crash the JVM. tracer.log(Level.SEVERE, "stream preparation exception", e); throw e; } catch (Error e) { // When these occur, it can cause the ensuing // FennelStorage.tupleStreamGraphClose() to crash the JVM. tracer.log(Level.SEVERE, "stream preparation error", e); throw e; } finally { if (!success) { if (newStreamGraph != null) { newStreamGraph.closeAllocation(); } } repos.endReposSession(); } } // implement FennelJavaStreamMap public long getJavaStreamHandle(int streamId) { final FennelJavaHandle handle = streamIdToHandleMap.get(streamId); assert handle != null : "No handle for stream #" + streamId; return handle.getLongHandle(); } // implement FennelJavaStreamMap public long getIndexRoot(long pageOwnerId) { FemLocalIndex index = indexMap.getIndexById(pageOwnerId); return indexMap.getIndexRoot(index); } /** * @return handle to Fennel database being accessed */ public FennelDbHandle getFennelDbHandle() { return fennelTxnContext.getFennelDbHandle(); } // implement FarragoSessionRuntimeContext public FarragoRepos getRepos() { return repos; } /** * Called when a nullable value is cast to a NOT NULL type. * * @param targetName target expression * @param nullableValue source value */ public void checkNotNull(String targetName, NullableValue nullableValue) { if (nullableValue.isNull()) { throw FarragoResource.instance().NullNotAllowed.ex( targetName); } } /** * Called when a nullable value is cast to a NOT NULL type. * * @param targetName target expression * @param obj source value */ public void checkNotNull(String targetName, Object obj) { if (null == obj) { throw FarragoResource.instance().NullNotAllowed.ex( targetName); } } // implement FarragoSessionRuntimeContext public void pushRoutineInvocation( FarragoSessionUdrContext udrContext, boolean allowSql) { // TODO jvs 19-Jan-2005: set system properties sqlj.defaultconnection // and sqlj.runtime per SQL:2003 13:12.1.2. Also other // context stuff. FarragoUdrInvocationFrame frame = new FarragoUdrInvocationFrame(); frame.context = this; frame.allowSql = allowSql; udrContext.setSession(session); frame.udrContext = udrContext; List stack = getInvocationStack(); stack.add(frame); } // implement FarragoSessionRuntimeContext public void popRoutineInvocation() { // TODO jvs 19-Jan-2005: see corresponding comment in // pushRoutineInvocation. List stack = getInvocationStack(); assert (!stack.isEmpty()); FarragoUdrInvocationFrame frame = stack.remove(stack.size() - 1); assert (frame.context == this); if (frame.connection != null) { try { frame.connection.close(); } catch (SQLException ex) { // TODO jvs 19-Jan-2005: standard mechanism for tracing // swallowed exceptions } finally { EnkiMDRepository mdrRepos = frame.context.getRepos().getEnkiMdrRepos(); mdrRepos.reattachSession(frame.reposSession); } } } // implement FarragoSessionRuntimeContext public void cancel() { synchronized (this) { // be sure only one thread tries to close the FennelStreamGraph if (isCanceled) { return; } // set isCanceled before aborting streamGraph to ensure // that flag is set when ResultSet sees END_OF_DATA isCanceled = true; } FennelStreamGraph streamGraphToAbort = streamGraph; if (streamGraphToAbort != null) { streamGraphToAbort.abort(); } // Synchronize so the execution handle doesn't get reset while // we're checking for its existence synchronized (this) { if (execHandle != null) { tracer.fine("Aborting statement execution"); execHandle.cancelExecution(); } } } // implement FarragoSessionRuntimeContext public void checkCancel() { if (isCanceled) { throw FarragoResource.instance().ExecutionAborted.ex(); } } // implement FarragoSessionRuntimeContext public void setExecutionHandle(FennelExecutionHandle execHandle) { synchronized (this) { this.execHandle = execHandle; } } // implement FarragoSessionRuntimeContext public void setCursorState(boolean active) { synchronized (cursorMonitor) { if (active) { // check before fetch checkCancel(); } cursorActive = active; if (!cursorActive) { cursorMonitor.notifyAll(); } } } // implement FarragoSessionRuntimeContext public void waitForCursor() { synchronized (cursorMonitor) { try { while (cursorActive) { cursorMonitor.wait(); } } catch (InterruptedException ex) { throw Util.newInternal(ex); } } } // implement FarragoSessionRuntimeContext public RuntimeException handleRoutineInvocationException( Throwable ex, String methodName) { // TODO jvs 19-Jan-2005: special SQLSTATE handling defined // in SQL:2003-13-15.1 return FarragoResource.instance().RoutineInvocationException.ex( methodName, ex); } private static List getInvocationStack() { List stack = threadInvocationStack.get(); if (stack == null) { stack = new ArrayList(); threadInvocationStack.set(stack); } return stack; } static FarragoUdrInvocationFrame getUdrInvocationFrame() { List stack = threadInvocationStack.get(); if ((stack == null) || (stack.isEmpty())) { throw new IllegalStateException("No UDR executing."); } FarragoUdrInvocationFrame frame = peekStackFrame(stack); return frame; } private static FarragoUdrInvocationFrame peekStackFrame( List stack) { assert (!stack.isEmpty()); return stack.get(stack.size() - 1); } /** * Creates a new default connection attached to the session of the current * thread. */ public static Connection newConnection() { List stack = getInvocationStack(); if (stack.isEmpty()) { throw FarragoResource.instance().NoDefaultConnection.ex(); } FarragoUdrInvocationFrame frame = peekStackFrame(stack); if (!frame.allowSql) { throw FarragoResource.instance().NoDefaultConnection.ex(); } if (frame.connection == null) { FarragoSessionConnectionSource connectionSource = frame.context.session.getConnectionSource(); frame.connection = connectionSource.newConnection(); // TODO jvs 19-Jan-2005: we're also supposed to make // sure the new connection has autocommit turned off. Need // to do that without disturbing the session. And could // enforce READS/MODIFIES SQL DATA access. EnkiMDRepository mdrRepos = frame.context.getRepos().getEnkiMdrRepos(); frame.reposSession = mdrRepos.detachSession(); } // NOTE jvs 19-Jan-2005: We automatically close the // connection in popRoutineInvocation, which is guaranteed // to be called because we generate it in a finally block. So // there's no need to track the connection as an allocation. return frame.connection; } public void setStatementClassLoader(ClassLoader statementClassLoader) { this.statementClassLoader = statementClassLoader; } public Class statementClassForName(String statementClassName) { try { if (null == statementClassLoader) { return Class.forName( statementClassName, true, statementClassLoader); } return statementClassLoader.loadClass(statementClassName); } catch (ClassNotFoundException e) { tracer.log( Level.SEVERE, "Could not load statement class: " + statementClassName, e); return null; } } // implement FarragoSessionRuntimeContext public RelDataType getRowTypeForResultSet(String resultSetName) { final RelDataType rowType = resultSetTypeMap.get(resultSetName); assert rowType != null : "no type for result set " + resultSetName; return rowType; } public FarragoSequenceAccessor getSequenceAccessor(String mofId) { return repos.getSequenceAccessor(mofId); } // implement FarragoSessionRuntimeContext public FarragoSession getSession() { return session; } /** * Handles an exception encountered by a stream while processing an input * row. The default implementation logs exceptions to the server trace file. * * @param row the input row object * @param ex the exception encountered * @param columnIndex index for the output column being calculated when an * exception was encountered, or zero if the filter condition was being * evaluated. This parameter may be -1 if not appropriate for the exception * @param tag an error handling tag specific to the runtime context. This * parameter may also be null * * @return the status of the error handler. While the default implementation * returns null, Farrago extensions may return more informative values, such * as TupleIter.NoDataReason. */ public Object handleRowError( SyntheticObject row, RuntimeException ex, int columnIndex, String tag) { return handleRowError(row, ex, columnIndex, tag, false); } /** * Handles a runtime exception, but allows warnings as well. * * @see #handleRowError(SyntheticObject, RuntimeException, int, String) */ public Object handleRowError( SyntheticObject row, RuntimeException ex, int columnIndex, String tag, boolean isWarning) { return handleRowErrorHelper( row.toString(), ex, columnIndex, tag, isWarning); } /** * Handles a runtime exception based on an array of column values rather * than on a SyntheticObject */ public Object handleRowError( String [] columnNames, Object [] columnValues, RuntimeException ex, int columnIndex, String tag, boolean isWarning) { return handleRowErrorHelper( Util.flatArrayToString(columnValues), ex, columnIndex, tag, isWarning); } /** * Handles runtime exception; if errorCode is non-null, exceptions are * deferred until all errors on a row are processed; not currently * implemented */ public Object handleRowError( String [] columnNames, Object [] columnValues, RuntimeException ex, int columnIndex, String tag, boolean isWarning, String errorCode, String columnName) { throw Util.needToImplement(this); } /** * Handles exception for row errors with deferred exceptions; not currently * implemented */ public void handleRowErrorCompletion(RuntimeException ex, String tag) { throw Util.needToImplement(this); } /** * Helper for various handleRowError methods */ private EigenbaseException handleRowErrorHelper( String row, RuntimeException ex, int columnIndex, String tag, boolean isWarning) { EigenbaseTrace.getStatementTracer().log( Level.WARNING, "Row level exception", makeRowError(ex, row, columnIndex, null)); return null; } /** * Makes a row error based on conventions for column index * * @param ex the runtime exception encountered * @param row string representing the row on which an exception occurred * @param index index of the column being processed at the time the * exception was encountered, or 0 for an error processing a conditional * expression, or -1 for a non-specific error * @param field optional column name, used in constructing the error message * when columnIndex > 0 * * @return a non-nested exception summarizing the row error */ protected EigenbaseException makeRowError( RuntimeException ex, String row, int index, String field) { FarragoResource resource = FarragoResource.instance(); String msgs = Util.getMessages(ex); if (index < 0) { return resource.JavaRowError.ex(row, msgs, ex); } else if (index == 0) { return resource.JavaCalcConditionError.ex(row, msgs, ex); } else { String fieldName = (field != null) ? field : Integer.toString(index); return resource.JavaCalcError.ex( fieldName, row, msgs, ex); } } // implement FennelJavaErrorTarget public Object handleRowError( String source, boolean isWarning, String msg, ByteBuffer byteBuffer, int index) { if (nativeContext == null) { nativeContext = new NativeRuntimeContext(this); } return nativeContext.handleRowError( source, isWarning, msg, byteBuffer, index); } /** * @return true if a UDR is currently being executed */ public static boolean inUdr() { List stack = threadInvocationStack.get(); if ((stack == null) || (stack.isEmpty())) { return false; } else { return true; } } public void detachMdrSession() { Util.permAssert( detachedSession == null, "FarragoRuntimeContext only supports a single detached session"); detachedSession = getRepos().getEnkiMdrRepos().detachSession(); } public void reattachMdrSession() { getRepos().getEnkiMdrRepos().reattachSession(detachedSession); detachedSession = null; } //~ Inner Classes ---------------------------------------------------------- /** * Inner class for taking care of closing streams without deallocating them. */ private static class StreamOwner extends FarragoCompoundAllocation { public void closeAllocation() { // traverse in reverse order ListIterator iter = allocations.listIterator(allocations.size()); if (tracer.isLoggable(Level.FINE)) { tracer.fine("closing stream owner with " + allocations); } while (iter.hasPrevious()) { FennelStreamGraph streamGraph = (FennelStreamGraph) iter.previous(); streamGraph.close(); } allocations.clear(); } } } // End FarragoRuntimeContext.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelTupleReader.java0000444000175000017500000000425311173714170026261 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTupleReader.java#12 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; /** * FennelTupleReader defines an interface for unmarshalling tuples returned by * Fennel. Implementations are generated by FennelToIteratorConverter for * unmarshalling specific tuple formats. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTupleReader.java#12 $ */ public interface FennelTupleReader { //~ Methods ---------------------------------------------------------------- /** * Unmarshals one tuple. * * @param byteBuffer read-only buffer containing marshalled tuple data; on * entry, the buffer position is at beginning of tuple * @param byteArray byte array underlying byteBuffer * @param sliceBuffer result of byteBuffer.slice(), for use in relative * offsets; on return, sliceBuffer position should be at the unaligned end * of tuple * * @return subclass-specific object containing unmarshalled tuple data */ Object unmarshalTuple( ByteBuffer byteBuffer, byte [] byteArray, ByteBuffer sliceBuffer); } // End FennelTupleReader.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoTransformImpl.java0000444000175000017500000001333611173714170027016 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoTransformImpl.java#13 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import net.sf.farrago.resource.*; import org.eigenbase.runtime.*; /** * FarragoTransformImpl provides a base class for generated implementations of * {@link FarragoTransform}. * * @author Julian Hyde, Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoTransformImpl.java#13 $ */ public abstract class FarragoTransformImpl implements FarragoTransform { //~ Instance fields -------------------------------------------------------- private TupleIter tupleIter; private FennelTupleWriter tupleWriter; private Object next; //~ Methods ---------------------------------------------------------------- /** * Initialze this FarragoTransformImpl. Generated FarragoTransform * implementations should pass their generated FennelTupleWriter and * TupleIter implementations here. A subclass (not an anonymous subclass) * may pass null for tupleWriter or * tupleIter iff it has a different way to read or write its data and * iff it overrides {@link #execute} and {@link #restart} as appropriate. * * @param tupleWriter FennelTupleWriter that can marshal this transform's * output tuple format. * @param tupleIter TupleIter that performs this transform's work */ protected void init(FennelTupleWriter tupleWriter, TupleIter tupleIter) { this.tupleWriter = tupleWriter; this.tupleIter = tupleIter; this.next = null; } /** * for named subclasses, not for generated transforms */ protected TupleIter getTupleIter() { return tupleIter; } public void setInputFetchTimeout(long msec) { tupleIter.setTimeout(msec, true); } /** * Execute this transform. Execution continues until the underlying {@link * #tupleIter} returns END_OF_DATA or UNDERFLOW or until the underlying * {@link #tupleWriter} can no longer marshal tuples into the output buffer. * * @param outputBuffer output ByteBuffer, written to via {@link * #tupleWriter} * @param quantum the maximum number of tuples to process before returning * * @return number of bytes marshaled into outputBuffer; 0 on END_OF_DATA; -1 * on UNDERFLOW */ public int execute(ByteBuffer outputBuffer, long quantum) { long tupleCount = 0; // If next is not null, then a row was previously fetched but // there wasn't room to marshal it. if (next == null) { Object o = tupleIter.fetchNext(); if (o == TupleIter.NoDataReason.END_OF_DATA) { return 0; } else if (o == TupleIter.NoDataReason.UNDERFLOW) { return -1; } next = o; } outputBuffer.order(ByteOrder.nativeOrder()); outputBuffer.clear(); for (;;) { // Before attempting to marshal tuple, record current start // position in case a partial marshalling attempt moves it. int startPosition = outputBuffer.position(); if (!tupleWriter.marshalTuple(outputBuffer, next)) { if (startPosition == 0) { // We were not able to marshal the entire tuple, // and so far we haven't even marshalled one tuple, // so there's no way we're going to make progress. throw FarragoResource.instance().JavaRowTooLong.ex( outputBuffer.remaining(), next.toString()); } else { // Not enough room to marshal the latest tuple, but we've // already got some earlier ones marshalled. break; } } // See note re: quantum as unsigned int. if (++tupleCount >= quantum) { next = null; break; } Object o = tupleIter.fetchNext(); if (o == TupleIter.NoDataReason.END_OF_DATA) { // Will return 0 on next call to this method -- we've already // marshaled at least one tuple that we need to return. next = null; break; } else if (o == TupleIter.NoDataReason.UNDERFLOW) { // We marshaled at least one tuple, so don't return -1. next = null; break; } next = o; } outputBuffer.flip(); return outputBuffer.limit(); } /** * Restart the underlying {@link #tupleIter}. */ public void restart() { tupleIter.restart(); } } // End FarragoTransformImpl.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoTupleIterResultSet.java0000444000175000017500000001774511173714170030021 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoTupleIterResultSet.java#20 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.sql.*; import java.util.logging.*; import net.sf.farrago.jdbc.*; import net.sf.farrago.session.*; import net.sf.farrago.trace.*; import net.sf.farrago.type.*; import net.sf.farrago.type.runtime.*; import org.eigenbase.reltype.*; import org.eigenbase.runtime.*; /** * FarragoTupleIterResultSet is a refinement of TupleIterResultSet which exposes * Farrago datatype semantics. * * @author John V. Sichi, Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoTupleIterResultSet.java#20 $ */ public class FarragoTupleIterResultSet extends TupleIterResultSet { //~ Static fields/initializers --------------------------------------------- protected static final Logger tracer = FarragoTrace.getFarragoTupleIterResultSetTracer(); private static final Logger jdbcTracer = FarragoTrace.getFarragoJdbcEngineDriverTracer(); //~ Instance fields -------------------------------------------------------- private FarragoSessionRuntimeContext runtimeContext; private RelDataType rowType; //~ Constructors ----------------------------------------------------------- public FarragoTupleIterResultSet( TupleIter tupleIter, Class clazz, RelDataType rowType, FarragoSessionRuntimeContext runtimeContext) { this( tupleIter, clazz, rowType, runtimeContext, new SyntheticColumnGetter(clazz)); } /** * Creates a new FarragoTupleIterResultSet object. * * @param tupleIter underlying iterator * @param clazz Class for objects which iterator will produce * @param rowType type info for rows produced * @param runtimeContext runtime context for this execution * @param columnGetter object used to read individual columns from the the * underlying iterator */ public FarragoTupleIterResultSet( TupleIter tupleIter, Class clazz, RelDataType rowType, FarragoSessionRuntimeContext runtimeContext, ColumnGetter columnGetter) { super(tupleIter, columnGetter); this.rowType = rowType; this.runtimeContext = runtimeContext; if (tracer.isLoggable(Level.FINE)) { tracer.fine(toString()); } } //~ Methods ---------------------------------------------------------------- /** * Signals that all aspects of opening this ResultSet have completed * successfully. After this method is called, the ResultSet must * (eventually) be closed or else resources may be leaked. */ public void setOpened() { if (runtimeContext != null) { // Immediately detach session. Another thread (think RMI) may be // the one to call next, we'll re-attach this session then. runtimeContext.detachMdrSession(); } } // implement ResultSet public boolean next() throws SQLException { boolean detachMdrSession = false; try { if (tracer.isLoggable(Level.FINE)) { tracer.fine(toString()); } if (runtimeContext != null) { // Inform context that cursor is becoming active, so any // subsequent cancel request has to wait until the // corresponding call in the finally block before cleaning up // the cursor. This also checks for any pending cancel. runtimeContext.setCursorState(true); runtimeContext.reattachMdrSession(); detachMdrSession = true; } boolean rc = super.next(); if (!rc) { if (runtimeContext != null) { FarragoSession session = runtimeContext.getSession(); if (session.isAutoCommit()) { // According to the Javadoc for // Connection.setAutoCommit, returning the last // row of a cursor in autocommit mode ends // the transaction. if (detachMdrSession) { // Close expects the session to be detached. runtimeContext.detachMdrSession(); detachMdrSession = false; } runtimeContext.setCursorState(false); close(); } } } return rc; } catch (Throwable ex) { // trace exceptions as part of JDBC API throw FarragoJdbcUtil.newSqlException(ex, jdbcTracer); } finally { if (runtimeContext != null) { if (detachMdrSession) { runtimeContext.detachMdrSession(); detachMdrSession = false; } // Inform context that we're done with cursor processing until // next fetch call. try { runtimeContext.setCursorState(false); } catch (Exception ex) { // trace exceptions as part of JDBC API throw FarragoJdbcUtil.newSqlException(ex, jdbcTracer); } } } } // implement ResultSet public ResultSetMetaData getMetaData() throws SQLException { return new FarragoResultSetMetaData(rowType); } // implement ResultSet public void close() throws SQLException { if (tracer.isLoggable(Level.FINE)) { tracer.fine(toString()); } FarragoSessionRuntimeContext allocationToClose = runtimeContext; if (allocationToClose != null) { // NOTE: this may be called reentrantly for daemon stmts, // so need special handling runtimeContext = null; // Lock session before sessionCtxt, to be consistent with global // locking strategy. In particular, FarragoDbStmtContext.close() // locks the session before it calls // FarragoSessionRuntimeContext.closeAllocation(). synchronized (allocationToClose.getSession()) { allocationToClose.closeAllocation(); } } super.close(); } // implement AbstractResultSet protected Object getRaw(int columnIndex) { Object obj = super.getRaw(columnIndex); if (obj instanceof SpecialDataValue) { SpecialDataValue specialValue = (SpecialDataValue) obj; obj = specialValue.getSpecialData(); wasNull = (obj == null); } else if (obj instanceof DataValue) { DataValue nullableValue = (DataValue) obj; obj = nullableValue.getNullableData(); wasNull = (obj == null); } else { wasNull = false; } return obj; } } // End FarragoTupleIterResultSet.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelOnlyResultSet.java0000444000175000017500000000776311173714170026652 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelOnlyResultSet.java#5 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.sql.*; import java.util.logging.*; import net.sf.farrago.fennel.tuple.*; import net.sf.farrago.session.*; import org.eigenbase.relopt.*; import org.eigenbase.reltype.*; import org.eigenbase.runtime.*; /** * FennelOnlyResultSet is a refinement of FarragoTupleIterResultSet, where the * result set consists of Fennel tuples. * * @author Zelaine Fong * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelOnlyResultSet.java#5 $ */ public class FennelOnlyResultSet extends FarragoTupleIterResultSet { //~ Constructors ----------------------------------------------------------- /** * Creates a new FennelOnlyResultSet object. * * @param tupleIter underlying iterator * @param rowType type info for rows produced * @param runtimeContext runtime context for this execution * @param metaData metadata representing the result set */ public FennelOnlyResultSet( TupleIter tupleIter, RelDataType rowType, FarragoSessionRuntimeContext runtimeContext, ResultSetMetaData metaData) { super( tupleIter, null, rowType, runtimeContext, new FennelColumnGetter(metaData, rowType)); if (tracer.isLoggable(Level.FINE)) { tracer.fine(toString()); } } //~ Methods ---------------------------------------------------------------- // implement AbstractResultSet protected Object getRaw(int columnIndex) { Object obj = super.getRaw(columnIndex); wasNull = (obj == null); return obj; } //~ Inner Classes ---------------------------------------------------------- /** * ColumnGetter that reads columns from a Fennel tuple * * @author Zelaine Fong */ private static class FennelColumnGetter implements ColumnGetter { final private ResultSetMetaData metaData; final private RelDataType rowType; /** * @param metaData metadata corresponding to the result set from which * the columns will be read * @param rowType row type of the tuple containing the columns to be * read */ public FennelColumnGetter( ResultSetMetaData metaData, RelDataType rowType) { this.metaData = metaData; this.rowType = rowType; } public String [] getColumnNames() { return RelOptUtil.getFieldNames(rowType); } public Object get( Object o, int columnIndex) { try { return FennelTupleResultSet.getRawColumnData( columnIndex, metaData, (FennelTupleData) o); } catch (SQLException e) { throw new RuntimeException(e); } } } } // End FennelOnlyResultSet.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelRowCount.java0000444000175000017500000000313411173714170025622 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelRowCount.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; /** * Class for holding the number of rows returned by a DML statement. DML * operators return a single scalar value of a synthetic type which matches this * template. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelRowCount.java#11 $ */ public class FennelRowCount { //~ Instance fields -------------------------------------------------------- /** * Number of rows affected by DML statement. */ public long ROWCOUNT; } // End FennelRowCount.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoUdrRuntime.java0000444000175000017500000002020511173714170026310 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoUdrRuntime.java#15 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import net.sf.farrago.catalog.*; import net.sf.farrago.fennel.*; import net.sf.farrago.session.*; import org.eigenbase.util.*; /** * FarragoUdrRuntime exposes a runtime support interface which can be used by * implementations of Farrago user-defined routines. For an example of how to * use this interface, see {@link * net.sf.farrago.test.FarragoTestUDR#generateRandomNumber}. * *

NOTE: By relying on this interface, your UDR becomes dependent on Farrago. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoUdrRuntime.java#15 $ */ public abstract class FarragoUdrRuntime { //~ Methods ---------------------------------------------------------------- /** * Accesses the context object for the calling UDR. * * @return context object, or null if none has been set yet */ public static Object getContext() { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); return frame.udrContext.getObject(); } /** * Stores the context object for the calling UDR. If the given context * object implements the {@link ClosableAllocation} interface, its * closeAllocation method will be called automatically when statement * execution ends. * * @param context new context object to set */ public static void setContext(Object context) { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); frame.udrContext.setObject(context); if (context instanceof ClosableAllocation) { frame.context.addAllocation((ClosableAllocation) context); } } /** * If this UDR invocation was generated by a {@link * net.sf.farrago.namespace.FarragoMedDataServer}, invokes that server's * {@link net.sf.farrago.namespace.FarragoMedDataServer#getRuntimeSupport} * method. Otherwise, throws {@link IllegalStateException}. * * @param param server-specific runtime parameter * * @return server-specific runtime support object */ public static Object getDataServerRuntimeSupport(Object param) { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); String serverMofId = frame.udrContext.getServerMofId(); if (serverMofId == null) { throw new IllegalStateException(); } return frame.context.getDataServerRuntimeSupport( serverMofId, param); } /** * Tests to see whether the statement invoking this UDR has been cancelled; * if so, an exception is thrown. UDR's which take a lot of CPU time can * call this periodically in order to be responsive to cancel within calls. */ public static void checkCancel() { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); frame.context.checkCancel(); } /** * Associates an execution handle with the context associated with the * executing UDR. * * @param execHandle the execution handle */ public static void setExecutionHandle(FennelExecutionHandle execHandle) { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); frame.context.setExecutionHandle(execHandle); } /** * Gets the session which called the UDR. Only system UDR's are allowed to * call this. * * @return a FarragoSession */ public static FarragoSession getSession() { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); return frame.udrContext.getSession(); } /** * Gets the FarragoRepos for this context. Only system UDR's are allowed to * call this. * * @return a FarragoRepos */ public static FarragoRepos getRepos() { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); return frame.udrContext.getRepos(); } /** * Forwards a row error to the runtime context. The runtime context then * decides how to process the error. For example, it might log the error, * send the error to a table, or cancel the statement. * * @param columnNames array of column names from the input stream * @param columnValues array of column values for the bad input row. * Primitive values such as long or int should be wrapped in Objects such as * Long or Int. Values should be printable via toString(). For example, * 2006-10-08 would be preferrable to Date@1ee80a. * @param ex the runtime exception to be handled * @param columnIndex the 1-based index of the column with the error. Since * the value 0 is reserved for filter conditions, the value -1 may be used * when a column index is not applicable. * @param tag a unique identifier for the source of the exception. It is * helpful for the tag to include information about the source. For example, * CleanseAddress[Id] may be more useful than [Id]. A timestamp suffix can * be informative and helps to satisfy the uniqueness requirement. * @param isWarning whether the exception is to be treated as a warning * * @return a server specific status value. A server may choose to return * null or to return a more detailed status such as {@link * org.eigenbase.runtime.TupleIter.NoDataReason} to indicate that the error * could not be processed. */ public static Object handleRowError( String [] columnNames, Object [] columnValues, RuntimeException ex, int columnIndex, String tag, boolean isWarning) { return handleRowError( columnNames, columnValues, ex, columnIndex, tag, isWarning, null, null); } /** * Forwards error to runtime context, if error code is non-null, exceptions * will be defered until all errors have been processed/logged for a row */ public static Object handleRowError( String [] columnNames, Object [] columnValues, RuntimeException ex, int columnIndex, String tag, boolean isWarning, String errorCode, String columnName) { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); return frame.context.handleRowError( columnNames, columnValues, ex, columnIndex, tag, isWarning, errorCode, columnName); } public static void handleRowErrorCompletion( RuntimeException ex, String tag) { FarragoUdrInvocationFrame frame = FarragoRuntimeContext.getUdrInvocationFrame(); frame.context.handleRowErrorCompletion(ex, tag); } /* * @return true if a UDR is currently executing */ public static boolean inUdr() { return FarragoRuntimeContext.inUdr(); } } // End FarragoUdrRuntime.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelTupleWriter.java0000444000175000017500000001064311173714170026333 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTupleWriter.java#19 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import net.sf.farrago.fennel.tuple.*; /** * FennelTupleWriter defines an interface for marshalling tuples to be sent to * Fennel. Implementations are responsible for marshalling specific tuple * formats. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTupleWriter.java#19 $ */ public abstract class FennelTupleWriter { //~ Static fields/initializers --------------------------------------------- /** * Matches fennel/tuple/TupleAccessor.cpp. */ private static long MAGIC_NUMBER = 0x9897ab509de7dcf5L; /** * Singleton helper for aligning tuple buffers correctly. */ private static FennelTupleAccessor tupleAligner = new FennelTupleAccessor(); //~ Methods ---------------------------------------------------------------- /** * Marshals one tuple if it can fit; otherwise, throws either {@link * BufferOverflowException} or {@link IndexOutOfBoundsException} (depending * on whether absolute or relative puts are used). * * @param sliceBuffer buffer to be filled with marshalled tuple data; on * entry, the buffer position is 0; on return, the buffer position should be * the unaligned end of the tuple * @param object subclass-specific object to be marshalled * * @exception BufferOverflowException see above * @exception IndexOutOfBoundsException see above */ protected abstract void marshalTupleOrThrow( ByteBuffer sliceBuffer, Object object); /** * Marshals one tuple if it can fit. * * @param byteBuffer buffer to be filled with marshalled tuple data, * starting at current buffer position; on return, the buffer position * should be the unaligned end of the tuple * @param object subclass-specific object to be marshalled * * @return whether the marshalled tuple fit in the available buffer space */ public boolean marshalTuple( ByteBuffer byteBuffer, Object object) { try { // REVIEW: is slice allocation worth it? ByteBuffer sliceBuffer = byteBuffer.slice(); sliceBuffer.order(byteBuffer.order()); // In case TupleAccessor's DEBUG_TUPLE_ACCESS is enabled, // store the correct magic number at the beginning of the // marshalled tuple. TODO: don't do this unless needed. sliceBuffer.putLong(0, MAGIC_NUMBER); marshalTupleOrThrow(sliceBuffer, object); int newPosition = byteBuffer.position() + sliceBuffer.position(); // add final alignment padding newPosition = tupleAligner.alignRoundUp(newPosition); byteBuffer.position(newPosition); } catch (BufferOverflowException ex) { return false; } catch (BufferUnderflowException ex) { // NOTE jvs 19-May-2006: We shouldn't need this case, // but JRockit mistakenly throws underflow instead of overflow. return false; } catch (IndexOutOfBoundsException ex) { return false; } catch (IllegalArgumentException ex) { // NOTE jvs 31-Aug-2004: The position() call throws this instead // of BufferOverflowException. return false; } return true; } } // End FennelTupleWriter.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FennelTransformTupleIter.java0000444000175000017500000001131311173714170027651 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTransformTupleIter.java#7 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.nio.*; import net.sf.farrago.fennel.*; /** * FennelTransformTupleIter implements the {@link * org.eigenbase.runtime.TupleIter} interfaces by reading tuples from a Fennel * JavaTransformExecStream. * *

FennelTransformTupleIter only deals with raw byte buffers; it delegates to * a {@link FennelTupleReader} object the responsibility to unmarshal individual * fields. * *

FennelTransformTupleIter's implementation of {@link #populateBuffer()} * does not block. * * @author Stephan Zuercher * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FennelTransformTupleIter.java#7 $ */ public class FennelTransformTupleIter extends FennelAbstractTupleIter { //~ Instance fields -------------------------------------------------------- private final int execStreamInputOrdinal; private final FennelStreamGraph streamGraph; private final FennelStreamHandle streamHandle; private final FennelStreamHandle inputStreamHandle; //~ Constructors ----------------------------------------------------------- /** * Creates a new FennelTransformTupleIter object. * * @param tupleReader FennelTupleReader to use to interpret Fennel data * @param streamGraph underlying FennelStreamGraph * @param streamHandle handle to underlying Fennel JavaTransformExecStream * @param inputStreamHandle handle to the Fennel ExecStream that this * TupleIter reads from -- used only for reset * @param inputOrdinal the input stream's ordinal in the underlying * JavaTransformExecStream * @param bufferSize number of bytes in buffer used for fetching from Fennel */ public FennelTransformTupleIter( FennelTupleReader tupleReader, FennelStreamGraph streamGraph, FennelStreamHandle streamHandle, FennelStreamHandle inputStreamHandle, int inputOrdinal, int bufferSize) { super(tupleReader); this.execStreamInputOrdinal = inputOrdinal; this.streamGraph = streamGraph; this.streamHandle = streamHandle; this.inputStreamHandle = inputStreamHandle; // In this implementation of FennelAbstractTupleIter, byteBuffer and // bufferAsArray are effectively final. In other implementations, they // might be set by populateBuffer. bufferAsArray = new byte[bufferSize]; byteBuffer = ByteBuffer.wrap(bufferAsArray); byteBuffer.order(ByteOrder.nativeOrder()); byteBuffer.clear(); byteBuffer.limit(0); } //~ Methods ---------------------------------------------------------------- // override FennelAbstractTupleIter public void restart() { super.restart(); bufferAsArray = byteBuffer.array(); byteBuffer.clear(); byteBuffer.limit(0); // a reset on streamHandle is what got us here -- pass it on streamGraph.restart(inputStreamHandle); } // implement TupleIter public void closeAllocation() { // REVIEW: SWZ: 2/23/2006: Deallocate byteBuffer here? } /** * Non-blocking implementation of {@link FennelTupleIter#populateBuffer()}. * * @return number of bytes read into {@link FennelTupleIter#byteBuffer}, 0 * for end of stream, less than 0 for no data available */ protected int populateBuffer() { byteBuffer.clear(); int cb = streamGraph.transformFetch( streamHandle, execStreamInputOrdinal, bufferAsArray); if (cb < 0) { // don't let anyone assume anything was read byteBuffer.limit(0); } return cb; } } // End FennelTransformTupleIter.java eigenbase-farrago-0.9.0/src/net/sf/farrago/runtime/FarragoRuntimeJdbcUtil.java0000444000175000017500000000461411173714170027264 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoRuntimeJdbcUtil.java#6 $ // Farrago is an extensible data management system. // Copyright (C) 2006-2009 The Eigenbase Project // Copyright (C) 2006-2009 SQLstream, Inc. // Copyright (C) 2006-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.runtime; import java.sql.*; import net.sf.farrago.jdbc.param.*; import org.eigenbase.reltype.*; import org.eigenbase.sql.type.*; /** * Provides runtime support for implementing JDBC interfaces. * * @author Angel Chang * @version $Id: //open/dev/farrago/src/net/sf/farrago/runtime/FarragoRuntimeJdbcUtil.java#6 $ */ public abstract class FarragoRuntimeJdbcUtil { //~ Methods ---------------------------------------------------------------- public static FarragoParamFieldMetaData newParamFieldMetaData( RelDataType type, int mode) { FarragoParamFieldMetaData fieldMeta = new FarragoParamFieldMetaData(); fieldMeta.nullable = type.isNullable() ? ParameterMetaData.parameterNullable : ParameterMetaData.parameterNoNulls; fieldMeta.type = type.getSqlTypeName().getJdbcOrdinal(); fieldMeta.typeName = type.getSqlTypeName().name(); // TODO: Get class name; fieldMeta.className = ""; fieldMeta.precision = type.getPrecision(); fieldMeta.scale = type.getSqlTypeName().allowsScale() ? type.getScale() : 0; // TODO: treat all numerics as signed fieldMeta.signed = SqlTypeUtil.isNumeric(type); fieldMeta.mode = mode; fieldMeta.paramTypeStr = type.toString(); return fieldMeta; } } // End FarragoRuntimeJdbcUtil.java eigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/0000755000175000017500000000000011173714170021663 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/package.html0000444000175000017500000000104011173714170024135 0ustar drazzibdrazzib Package net.sf.farrago.plugin Defines Farrago plugin infrastructure.
Revision $Id: //open/dev/farrago/src/net/sf/farrago/plugin/package.html#6 $
Copyright Copyright (C) 2005-2009 The Eigenbase Project
Copyright (C) 2005-2009 SQLstream, Inc.
Copyright (C) 2005-2009 LucidEra, Inc.
Author John V. Sichi
eigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/FarragoAbstractPluginBase.java0000444000175000017500000002113711173714170027547 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoAbstractPluginBase.java#15 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plugin; import java.sql.*; import java.util.*; import net.sf.farrago.resource.*; /** * FarragoAbstractPluginBase is an abstract base for classes used to build * implementations of {@link FarragoPlugin}. Instances of this class are not * necessarily direct implementations of the FarragoPlugin interface itself; * they may be sub-components of the plugin. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoAbstractPluginBase.java#15 $ */ public class FarragoAbstractPluginBase { //~ Static fields/initializers --------------------------------------------- /** * A zero-length array of DriverPropertyInfo. */ public static final DriverPropertyInfo [] EMPTY_DRIVER_PROPERTIES = new DriverPropertyInfo[0]; public static final String [] BOOLEAN_CHOICES_DEFAULT_FALSE = { "FALSE", "TRUE" }; public static final String [] BOOLEAN_CHOICES_DEFAULT_TRUE = { "TRUE", "FALSE" }; //~ Methods ---------------------------------------------------------------- /** * Verifies that a property has been set, throwing an exception if has not. * * @param props properties to check * @param propName name of required property * * @exception EigenbaseException if property is not set */ public static void requireProperty( Properties props, String propName) { if (props.getProperty(propName) == null) { throw FarragoResource.instance().PluginPropRequired.ex(propName); } } /** * Gets the value of a long integer property. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value * * @exception EigenbaseException if property is set with non-integer value */ public static long getLongProperty( Properties props, String propName, long defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } else { try { return Long.parseLong(s); } catch (NumberFormatException ex) { throw FarragoResource.instance().PluginInvalidLongProp.ex( s, propName); } } } /** * Gets the value of an integer property. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value * * @exception EigenbaseException if property is set with non-integer value */ public static int getIntProperty( Properties props, String propName, int defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } else { try { return Integer.parseInt(s); } catch (NumberFormatException ex) { throw FarragoResource.instance().PluginInvalidIntProp.ex( s, propName); } } } /** * Gets the value of an short property. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value * * @exception EigenbaseException if property is set with non-short value */ public static short getShortProperty( Properties props, String propName, short defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } else { try { return Short.parseShort(s); } catch (NumberFormatException ex) { throw FarragoResource.instance().PluginInvalidShortProp.ex( s, propName); } } } /** * Gets the value of a byte property. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value * * @exception EigenbaseException if property is set with non-short value */ public static byte getByteProperty( Properties props, String propName, byte defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } else { try { return Byte.parseByte(s); } catch (NumberFormatException ex) { throw FarragoResource.instance().PluginInvalidByteProp.ex( s, propName); } } } /** * Gets the value of an float property. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value * * @exception EigenbaseException if property is set with non-short value */ public static float getFloatProperty( Properties props, String propName, float defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } else { try { return Float.parseFloat(s); } catch (NumberFormatException ex) { throw FarragoResource.instance().PluginInvalidFloatProp.ex( s, propName); } } } /** * Gets the value of an double property. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value * * @exception EigenbaseException if property is set with non-short value */ public static double getDoubleProperty( Properties props, String propName, double defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } else { try { return Double.parseDouble(s); } catch (NumberFormatException ex) { throw FarragoResource.instance().PluginInvalidDoubleProp.ex( s, propName); } } } /** * Gets the value of a boolean property, or a default value if the property * does not exist. Returns true if the property exists, and its * value is 1, t, true or * yes; the default value if it does not exist; false * otherwise. * * @param props property set * @param propName name of property * @param defaultValue value to return if property is not set * * @return property value */ public static boolean getBooleanProperty( Properties props, String propName, boolean defaultValue) { String s = props.getProperty(propName); if (s == null) { return defaultValue; } return s.equalsIgnoreCase("1") || s.equalsIgnoreCase("t") || s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("on"); } } // End FarragoAbstractPluginBase.java eigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/FarragoPlugin.java0000444000175000017500000000756211173714170025276 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPlugin.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plugin; import java.sql.*; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.util.*; /** * FarragoPlugin defines an abstract plugin interface. Some JDBC infrastructure * is borrowed ({@link java.sql.SQLException} and {@link * java.sql.DriverPropertyInfo}). The property info calls are designed to work * in the same iterative fashion as {@link java.sql.Driver#getPropertyInfo}. * *

Implementations of FarragoPlugin must provide a public default constructor * in order to be loaded via DDL statements. FarragoPlugin extends {@link * FarragoAllocation}; when closeAllocation is called, all resources acquired by * the plugin should be released. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPlugin.java#11 $ */ public interface FarragoPlugin extends FarragoAllocation { //~ Methods ---------------------------------------------------------------- /** * Obtains a suggested name for this plugin in the SQL catalog. * * @return suggested name */ public String getSuggestedName(); /** * Obtains a description of this plugin. * * @param locale Locale for formatting description * * @return localized description */ public String getDescription(Locale locale); /** * Obtains information about the properties applicable to plugin * initialization (the props parameter to the initialize method). * * @param locale Locale for formatting property info * @param props proposed list of property name/value pairs which will be * sent to initialize() * * @return 0 or more property info descriptors */ public DriverPropertyInfo [] getPluginPropertyInfo( Locale locale, Properties props); /** * Initializes this plugin with a given set of properties. This is called * after an uninitialized instance has been created via Class.forName. As * much validation as possible should be performed. * * @param repos FarragoRepos which can be used for metadata access * @param props plugin properties * * @exception SQLException if plugin initialization is unsuccessful */ public void initialize( FarragoRepos repos, Properties props) throws SQLException; /** * set the library name used to initialize this plugin * * @param libraryName library name */ public void setLibraryName(String libraryName); /** * return the library name used to initialize this plugin * * @return library name */ public String getLibraryName(); /** * return the options with which this plugin was initialized * * @return plugin properties */ public Properties getProperties(); } // End FarragoPlugin.java eigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/FarragoPluginCache.java0000444000175000017500000001243111173714170026211 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPluginCache.java#20 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plugin; import java.util.*; import net.sf.farrago.catalog.*; import net.sf.farrago.resource.*; import net.sf.farrago.util.*; /** * FarragoPluginCache is an abstract private cache for loading instances of * {@link FarragoPlugin} (and their component sub-objects). It requires an * underlying shared {@link FarragoObjectCache}. * *

This class is only a partial implementation. For an example of how to * build a full implementation, see {@link * net.sf.farrago.namespace.util.FarragoDataWrapperCache}. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPluginCache.java#20 $ */ public abstract class FarragoPluginCache extends FarragoCompoundAllocation { //~ Instance fields -------------------------------------------------------- private final Map mapMofIdToPlugin; private final FarragoObjectCache sharedCache; private final FarragoRepos repos; private final FarragoPluginClassLoader classLoader; //~ Constructors ----------------------------------------------------------- /** * Creates an empty cache. * * @param owner FarragoAllocationOwner for this cache, to make sure * everything gets discarded eventually * @param sharedCache underlying shared cache * @param repos FarragoRepos for wrapper initialization */ public FarragoPluginCache( FarragoAllocationOwner owner, FarragoObjectCache sharedCache, FarragoPluginClassLoader classLoader, FarragoRepos repos) { owner.addAllocation(this); this.sharedCache = sharedCache; this.repos = repos; this.classLoader = classLoader; this.mapMofIdToPlugin = new HashMap(); } //~ Methods ---------------------------------------------------------------- /** * @return the underlying repos */ public FarragoRepos getRepos() { return repos; } /** * @return the underlying shared cache */ public FarragoObjectCache getSharedCache() { return sharedCache; } /** * @return mapMofIdToPlugin */ public Map getMapMofIdToPlugin() { return mapMofIdToPlugin; } /** * Searches this cache for a plugin object identified by its catalog MofId. * * @param mofId MofId of plugin object being loaded * * @return cached instance or null if not yet cached */ protected Object searchPrivateCache(String mofId) { return mapMofIdToPlugin.get(mofId); } /** * Adds a plugin object to this cache. * * @param entry pinned entry from underlying shared cache; key must be * plugin object's catalog MofId * * @return cached plugin object */ protected Object addToPrivateCache(FarragoObjectCache.Entry entry) { // take ownership of the pinned cache entry addAllocation(entry); Object obj = entry.getValue(); mapMofIdToPlugin.put((String) entry.getKey(), obj); return obj; } /** * Initializes a plugin instance. * * @param libraryName filename of jar containing plugin implementation * @param jarAttributeName name of jar attribute to use to determine class * name * @param options options with which to initialize plugin * * @return initialized plugin */ protected FarragoPlugin initializePlugin( String libraryName, String jarAttributeName, Properties options) { Class pluginClass = classLoader.loadClassFromLibraryManifest( libraryName, jarAttributeName); FarragoPlugin plugin; try { Object obj = classLoader.newPluginInstance(pluginClass); assert (obj instanceof FarragoPlugin) : obj.getClass(); plugin = (FarragoPlugin) obj; plugin.initialize(repos, options); plugin.setLibraryName(libraryName); } catch (Throwable ex) { throw FarragoResource.instance().PluginInitFailed.ex( repos.getLocalizedObjectName(libraryName), ex); } return plugin; } } // End FarragoPluginCache.java eigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/FarragoPluginClassLoader.java0000444000175000017500000002151611173714170027406 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPluginClassLoader.java#15 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plugin; import java.net.*; import java.util.*; import java.util.jar.*; import java.util.logging.*; import net.sf.farrago.resource.*; import net.sf.farrago.trace.*; import net.sf.farrago.util.*; /** * FarragoPluginClassLoader allows plugin jars to be added to the ClassLoader * dynamically. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPluginClassLoader.java#15 $ */ public class FarragoPluginClassLoader extends URLClassLoader { //~ Static fields/initializers --------------------------------------------- private static final Logger tracer = FarragoTrace.getRuntimeContextTracer(); /** * Prefix used to indicate that a wrapper library is loaded directly from a * class rather than a jar. TODO: get rid of this and use only * LIBRARY_CLASS_PREFIX2. */ public static final String LIBRARY_CLASS_PREFIX1 = "class "; /** * New alternative to LIBRARY_CLASS_PREFIX1. */ public static final String LIBRARY_CLASS_PREFIX2 = "class:"; /** * Attribute name used in jar manifest for identifying the class to be used * as a plugin factory. */ public static final String PLUGIN_FACTORY_CLASS_ATTRIBUTE = "PluginFactoryClassName"; /** * Attribute name used in jar manifest for identifying the XMI file to be * used as a model extension. */ public static final String PLUGIN_MODEL_ATTRIBUTE = "PluginModel"; //~ Instance fields -------------------------------------------------------- private final Set urlSet; //~ Constructors ----------------------------------------------------------- public FarragoPluginClassLoader() { // NOTE jvs 8-Aug-2006: use context classloader to make // Farrago work correctly within a J2EE app server. super(new URL[0], Thread.currentThread().getContextClassLoader()); urlSet = new HashSet(); } public FarragoPluginClassLoader(ClassLoader parentClassLoader) { super(new URL[0], parentClassLoader); urlSet = new HashSet(); } //~ Methods ---------------------------------------------------------------- /** * Adds a URL from which plugins can be loaded. * * @param url URL to add */ public void addPluginUrl(URL url) { if (urlSet.contains(url)) { return; } addURL(url); urlSet.add(url); } /** * Loads a Java class from a library (either a jarfile using a manifest to * get the classname, or else a named class from the classpath). * * @param libraryName filename of jar containing plugin implementation * @param jarAttributeName name of jar attribute to use to determine class * name * * @return loaded class */ public Class loadClassFromLibraryManifest( String libraryName, String jarAttributeName) { try { libraryName = FarragoProperties.instance().expandProperties(libraryName); if (isLibraryClass(libraryName)) { String className = getLibraryClassReference(libraryName); return Class.forName(className); } else { JarFile jar = new JarFile(libraryName); Manifest manifest = jar.getManifest(); String className = manifest.getMainAttributes().getValue(jarAttributeName); if (className == null) { throw FarragoResource.instance().PluginManifestMissing.ex( libraryName, jarAttributeName); } return loadClassFromJarUrl( "file:" + libraryName, className); } } catch (Throwable ex) { throw FarragoResource.instance().PluginJarLoadFailed.ex( libraryName, ex); } } protected Class findClass(String name) throws ClassNotFoundException { try { return super.findClass(name); } catch (ClassNotFoundException cnfe) { return getParent().loadClass(name); } } /** * Loads a Java class from a jar URL, using the manifest to determine the * classname. * * @param jarUrl URL of jar containing plugin implementation * @param jarAttributeName name of jar attribute to use to determine class * name * * @return loaded class */ public Class loadClassFromJarUrlManifest( String jarUrl, String jarAttributeName) { if (isLibraryClass(jarUrl)) { try { String className = getLibraryClassReference(jarUrl); return Class.forName(className); } catch (Throwable ex) { throw FarragoResource.instance().PluginJarLoadFailed.ex( jarUrl, ex); } } jarUrl = FarragoProperties.instance().expandProperties(jarUrl); String className; try { URL url = new URL("jar:" + jarUrl + "!/"); JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); Manifest manifest = jarConnection.getManifest(); className = manifest.getMainAttributes().getValue(jarAttributeName); } catch (Throwable ex) { throw FarragoResource.instance().PluginJarLoadFailed.ex( jarUrl, ex); } return loadClassFromJarUrl(jarUrl, className); } /** * Loads a Java class from a jar URL. * * @param jarUrl URL for jar containing class implementation * @param className name of class to load * * @return loaded class */ public Class loadClassFromJarUrl( String jarUrl, String className) { try { URL url = new URL(jarUrl); addPluginUrl(url); return loadClass(className); } catch (Throwable ex) { throw FarragoResource.instance().PluginJarClassLoadFailed.ex( className, jarUrl, ex); } } /** * Constructs a new object instance of a plugin class, making sure the * thread's context ClassLoader is set to this for the duration * of the construction. * * @param pluginClass class to instantiate * * @return new object */ public Object newPluginInstance(Class pluginClass) throws InstantiationException, IllegalAccessException { Thread currentThread = Thread.currentThread(); ClassLoader savedClassLoader = currentThread.getContextClassLoader(); try { currentThread.setContextClassLoader(this); return pluginClass.newInstance(); } finally { currentThread.setContextClassLoader(savedClassLoader); } } /** * Tests whether a library name references a Java class directly rather than * a jar. * * @param libraryName library name to be tested * * @return true iff libraryName references a Java class */ public static boolean isLibraryClass(String libraryName) { return libraryName.startsWith(LIBRARY_CLASS_PREFIX1) || libraryName.startsWith(LIBRARY_CLASS_PREFIX2); } /** * From a library name which references a Java class directly, obtains the * class reference (possibly with trailing context such as a method name). * * @param libraryName library name to be parsed * * @return class name */ public static String getLibraryClassReference(String libraryName) { assert (isLibraryClass(libraryName)); return libraryName.substring(LIBRARY_CLASS_PREFIX2.length()); } } // End FarragoPluginClassLoader.java eigenbase-farrago-0.9.0/src/net/sf/farrago/plugin/FarragoPluginInfoList.java0000444000175000017500000000765411173714170026750 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPluginInfoList.java#11 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2005-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version approved by The Eigenbase Project. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.farrago.plugin; import java.sql.*; import java.util.*; /** * FarragoPluginInfoList is a helper class for building up the arrays of * DriverPropertyInfo returned by various getXXXPropertyInfo calls. * * @author John V. Sichi * @version $Id: //open/dev/farrago/src/net/sf/farrago/plugin/FarragoPluginInfoList.java#11 $ */ public class FarragoPluginInfoList { //~ Instance fields -------------------------------------------------------- private Properties defaultProps; private List propertyInfoList; //~ Constructors ----------------------------------------------------------- /** * Creates an empty info set. * * @param defaultProps Properties in which to look up default values */ public FarragoPluginInfoList(Properties defaultProps) { this.defaultProps = defaultProps; propertyInfoList = new ArrayList(); } //~ Methods ---------------------------------------------------------------- /** * Adds optional property information. * * @param propertyName name of the property * @param defaultValue String representation of default value to use if * property name not present in defaultProps * @param description localized description * * @return created info (the choices attribute can be set after return) */ public DriverPropertyInfo addOptionalPropertyInfo( String propertyName, String defaultValue, String description) { String value = defaultProps.getProperty(propertyName); if (value == null) { value = defaultValue; } DriverPropertyInfo info = new DriverPropertyInfo(propertyName, value); propertyInfoList.add(info); info.description = description; return info; } /** * Adds required property information. * * @param propertyName name of the property * @param defaultValue String representation of default value to use if * property name not present in defaultProps * @param description localized description * * @return created info (the choices attribute can be set after return) */ public DriverPropertyInfo addRequiredPropertyInfo( String propertyName, String defaultValue, String description) { DriverPropertyInfo info = addOptionalPropertyInfo(propertyName, defaultValue, description); info.required = true; return info; } /** * Converts the list built up with addXXXPropertyInfo to an array suitable * for return from a getXXXPropertyInfo call. * * @return the converted array */ public DriverPropertyInfo [] toArray() { return propertyInfoList.toArray( FarragoAbstractPluginBase.EMPTY_DRIVER_PROPERTIES); } } // End FarragoPluginInfoList.java eigenbase-farrago-0.9.0/src/net/sf/farrago/parser/0000755000175000017500000000000011173714170021661 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/src/net/sf/farrago/parser/CommonDdlParser.jj0000444000175000017500000022266211173714170025247 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/src/net/sf/farrago/parser/CommonDdlParser.jj#74 $ // Farrago is an extensible data management system. // Copyright (C) 2005-2009 The Eigenbase Project // Copyright (C) 2004-2009 SQLstream, Inc. // Copyright (C) 2005-2009 LucidEra, Inc. // Portions Copyright (C) 2003-2009 John V. Sichi // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later Eigenbase-approved version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // NOTE jvs 1-Feb-2005: convenience functions belong in // FarragoAbstractParserImpl, not here, unless they depend on // information which is only available in the generated parser class // (e.g. token). /***************************************** * Convenience Functions * *****************************************/ JAVACODE SqlParserPos getEndPos() { return new SqlParserPos( token.beginLine, token.beginColumn + token.image.length()); } /***************************************** * Syntactical Descriptions * *****************************************/ SqlIdentifier CompoundIdentifier2() : { List list = new ArrayList(); String p; SqlParserPos pos; } { p = Identifier() { list.add(p); pos = getPos(); } [ p = Identifier() { list.add(p); pos = pos.plus(getPos()); } ] { return new SqlIdentifier(SqlParserUtil.toStringArray(list), pos); } } SqlIdentifier CompoundIdentifier3() : { List list = new ArrayList(); String p; SqlParserPos pos; } { p = Identifier() { list.add(p); pos = getPos(); } [ p = Identifier() { list.add(p); pos = pos.plus(getPos()); } [ p = Identifier() { list.add(p); pos = pos.plus(getPos()); } ] ] { return new SqlIdentifier(SqlParserUtil.toStringArray(list), pos); } } String QuotedString() : { Token t; } { t = { return SqlParserUtil.parseString(t.image); } } /** * Parses an SQL statement followed by the end-of-file symbol. * * @return top-level CWM object affected for DDL statement, or top-level SqlNode * for DML or query statement */ Object FarragoSqlStmtEof() : { Object obj; } { ( obj = DdlStmtEof() | ( /* * Insure that a read-only repository transaction is started. * Note that view expansion can cause a second call into the * parser, which requires us to avoid attempting to start * the read txn twice. */ { FarragoReposTxnContext reposTxnContext = farragoParser.getStmtValidator().getReposTxnContext(); if (!reposTxnContext.isReadTxnInProgress()) { reposTxnContext.beginLockedTxn(true); } } obj = SqlStmtEof() | obj = PsmBody() ) ) { return obj; } } DdlStmt DdlStmtEof() : { CwmModelElement modelElement; DdlStmt ddlStmt; SqlNode expr; DdlReplaceOptions replaceOptions = new DdlReplaceOptions(); SqlIdentifier newName; FarragoReposTxnContext reposTxnContext = farragoParser.getStmtValidator().getReposTxnContext(); } { ( ( { reposTxnContext.beginLockedTxn(false); } [ ( ) { replaceOptions.setIsReplace(true); } [ ( newName = SimpleIdentifier() ) { replaceOptions.setNewName(newName); } ] ] ( modelElement = SchemaDefinition() | LOOKAHEAD(2) modelElement = DataWrapperDefinition() | modelElement = SchemaObjectDefinition() | modelElement = IndexDefinition(null) | modelElement = DataServerDefinition() | modelElement = UserDefinition() | modelElement = RoleDefinition() | modelElement = ExtensionModelDefinition() | modelElement = LabelDefinition() ) { ddlStmt = newDdlCreateStmt(modelElement, replaceOptions); } ) | ( { reposTxnContext.beginLockedTxn(false); // assume RESTRICT; CascadeOption() may override dropRestrict = true; } ( ( modelElement = SchemaDrop() | modelElement = TableDrop() | modelElement = IndexDrop() | modelElement = ViewDrop() | modelElement = RoutineDrop() | modelElement = UserDefinedTypeDrop() | modelElement = UserDefinedOrderingDrop() | modelElement = JarDrop() | modelElement = DataServerDrop() | LOOKAHEAD(2) modelElement = DataWrapperDrop() | LOOKAHEAD(2) modelElement = ForeignTableDrop() | modelElement = UserDrop() | modelElement = RoleDrop() | modelElement = ExtensionModelDrop() ) { ddlStmt = newDdlDropStmt(modelElement,dropRestrict); } | modelElement = LabelDrop() { ddlStmt = newDdlDropLabelStmt(modelElement,dropRestrict); } ) ) | ( { reposTxnContext.beginLockedTxn(true); } ( modelElement = TableIdentifier() ) { ddlStmt = new DdlTruncateStmt(modelElement); } ) | ( { reposTxnContext.beginLockedTxn(false); } ( expr = Expression(ExprContext.ACCEPT_NONQUERY) { ddlStmt = new DdlSetCatalogStmt(expr); } | expr = Expression(ExprContext.ACCEPT_NONQUERY) { ddlStmt = new DdlSetSchemaStmt(expr); } | expr = Expression(ExprContext.ACCEPT_NONQUERY) { ddlStmt = new DdlSetPathStmt(expr); } ) ) | ( { reposTxnContext.beginLockedTxn(false); } ( ddlStmt = SystemParamAssignment() | ddlStmt = CatalogExtension() | ddlStmt = CatalogReplace() | ddlStmt = DeallocateOld() ) | { reposTxnContext.beginLockedTxn(false); } ( ddlStmt = SessionImplementation() | ddlStmt = SessionParamAssignment() ) |
{ reposTxnContext.beginLockedTxn(false); ddlStmt = AlterTableStmt(); } | { reposTxnContext.beginLockedTxn(false); ddlStmt = ExtensionModelAlter(); } ) | { reposTxnContext.beginLockedTxn(false); } ( ddlStmt = GrantRoleStmt() | ddlStmt = GrantPrivStmt() ) | { reposTxnContext.beginLockedTxn(false); ddlStmt = new DdlCheckpointStmt(); } | { reposTxnContext.beginLockedTxn(false); ddlStmt = new DdlCommitStmt(); } | { reposTxnContext.beginLockedTxn(false); } ddlStmt = Rollback() | { reposTxnContext.beginLockedTxn(false); } ddlStmt = Savepoint() | { reposTxnContext.beginLockedTxn(false); } ddlStmt = ReleaseSavepoint() | { reposTxnContext.beginLockedTxn(false); } ddlStmt = ImportForeignSchemaStmt() | { // During the initial prepare of an analyze statement, we only // need to acquire shared locks since we're only reading from the // catalogs. During catalog update, we'll start a new write xact reposTxnContext.beginLockedTxn(true); } ddlStmt = AnalyzeStmt() ) { return ddlStmt; } } // TODO: support non-topological order of object definition, e.g. a // referencing table before a referenced table FemLocalSchema SchemaDefinition() : { FemLocalSchema schema; SqlIdentifier schemaName, userName; boolean pathDefined = false; SqlNode description; } { schemaName = CompoundIdentifier2() { schema = getRepos().newFemLocalSchema(); if (schemaName.names.length == 2) { CwmCatalog catalog = farragoParser.getStmtValidator().findCatalog( schemaName.names[0]); schema.setNamespace(catalog); schema.setName(schemaName.names[1]); } else { schema.setNamespace( farragoParser.getStmtValidator().getDefaultCatalog()); schema.setName(schemaName.getSimple()); } } [ userName = SimpleIdentifier() ] { // TODO: store userName } [ SchemaPath(schema) { pathDefined = true; } ] { if (!pathDefined) { // implicit default path is just this schema itself FemSqlpathElement element = getRepos().newFemSqlpathElement(); element.setSearchedSchemaCatalogName( schema.getNamespace().getName()); element.setSearchedSchemaName( schema.getName()); schema.getPathElement().add(element); } // set up context which will prevail for any object // definitions included in this schema definition farragoParser.getDdlValidator().setCreatedSchemaContext(schema); } OptionalDescription(schema) ( SchemaObjectDefinition() ) * { // TODO: character set, all that jazz return schema; } } CwmModelElement SchemaObjectDefinition() : { CwmModelElement modelElement; } { ( modelElement = TableDefinition() | modelElement = ViewDefinition() | LOOKAHEAD(2) modelElement = ForeignTableDefinition() | modelElement = FunctionDefinition() | modelElement = ProcedureDefinition() | modelElement = ConstructorDefinition() | modelElement = JarDefinition() | modelElement = UserDefinedTypeDefinition() | modelElement = UserDefinedOrderingDefinition() | modelElement = ExtensionModelSchemaObjDefinition() ) { return modelElement; } } void SchemaPath(FemLocalSchema schema) : { List searchPath; } { searchPath = SearchPath() { Iterator iter = searchPath.iterator(); while (iter.hasNext()) { CwmSchema searchedSchema = (CwmSchema) iter.next(); if (!searchedSchema.getNamespace().equals(schema.getNamespace())) { throw FarragoResource.instance().ValidatorPathBadCatalog.ex( getRepos().getLocalizedObjectName( searchedSchema.getNamespace()), getRepos().getLocalizedObjectName( schema.getNamespace())); } FemSqlpathElement element = getRepos().newFemSqlpathElement(); element.setSearchedSchemaCatalogName( searchedSchema.getNamespace().getName()); element.setSearchedSchemaName( searchedSchema.getName()); schema.getPathElement().add(element); } } } List SearchPath() : { List list = new ArrayList(); } { SearchPathElement(list) ( SearchPathElement(list) ) * { return list; } } void SearchPathElement(List list) : { SqlIdentifier id; } { id = CompoundIdentifier2() { FemLocalSchema searchedSchema = farragoParser.getStmtValidator().findSchema(id); list.add(searchedSchema); } } // TODO: support non-topological order of table element definition, e.g. a // referencing constraint definition before a referenced column definition CwmTable TableDefinition() : { FemStoredTable table; FemDataServer server = null; } { ( table = UnscopedTableDefinition() | table = ScopedTableDefinition() ) [ server = DataServerReference() ] OptionalStorageOptions(table) ( LOOKAHEAD(2) IndexDefinition(table) ) * { if (server == null) { server = farragoParser.getStmtValidator().getDefaultLocalDataServer(); } table.setServer(server); return table; } } FemLocalTable UnscopedTableDefinition() : { FemLocalTable table; SqlIdentifier qualifiedTableName; } {
{ table = getRepos().newFemLocalTable(); } qualifiedTableName = CompoundIdentifier3() { farragoParser.getDdlValidator().setSchemaObjectName( table,qualifiedTableName); table.setModality(ModalityTypeEnum.MODALITYTYPE_RELATIONAL); } TableElementList(table) OptionalSampleList(table, false) OptionalDescription(table) { return table; } } FemLocalTable ScopedTableDefinition() : { FemLocalTable table; String scope; String commitOption; } { table = UnscopedTableDefinition() { table.setTemporary(true); // TODO: support LOCAL (as "MODULE") scope = "SESSION"; commitOption = "DELETE"; } [ ( { commitOption = "PRESERVE"; } | { commitOption = "DELETE"; } ) ] { // TODO: add commitOption to FemLocalTable, since CWM doesn't // have a place for it? table.setTemporaryScope(scope + ":COMMIT=" + commitOption); return table; } } FemLocalView ViewDefinition() : { FemLocalView view; SqlIdentifier qualifiedViewName; SqlNode query, description; List columnNameList; SqlParserPos defStart, defEnd; } { { view = getRepos().newFemLocalView(); } qualifiedViewName = CompoundIdentifier3() { farragoParser.getDdlValidator().setSchemaObjectName( view,qualifiedViewName); view.setModality(ModalityTypeEnum.MODALITYTYPE_RELATIONAL); } [ columnNameList = SimpleIdentifierCommaList() { Iterator columnNameIter = columnNameList.iterator(); while (columnNameIter.hasNext()) { String columnName = ((SqlIdentifier) columnNameIter.next()).getSimple(); CwmColumn column = getRepos().newFemViewColumn(); column.setName(columnName); view.getFeature().add(column); } } ] OptionalDescription(view) { defStart = getEndPos(); } query = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY) { defEnd = getEndPos(); // NOTE: we accept ORDER BY on the view definition, even though // that's not standard SQL, and leave it up to the validator to // decide what to do with it String bodyText = farragoParser.getSubstring(defStart, defEnd); CwmQueryExpression queryExpr = getRepos().newCwmQueryExpression(); queryExpr.setLanguage("SQL"); bodyText = farragoParser.getDdlValidator().setParserOffset( view, defStart, bodyText); queryExpr.setBody(bodyText); view.setQueryExpression(queryExpr); return view; } } FemLocalIndex IndexDefinition(CwmTable table) : { FemLocalIndex index; SqlIdentifier indexName; CwmTable specifiedTable; List columnNameList; boolean clustered = false; } { [ { clustered = true; } ] { index = getRepos().newFemLocalIndex(); } indexName = SimpleIdentifier() { index.setName(indexName.getSimple()); } specifiedTable = TableIdentifier() { if (table == null) { table = specifiedTable; } else { // TODO: move rule down into validator if (!table.equals(specifiedTable)) { throw farragoParser.getDdlValidator().newPositionalError( index, FarragoResource.instance().ValidatorIndexBadTable.ex()); } } index.setSpannedClass(table); if (clustered) { index.setClustered(true); } index.setSorted(true); index.setUnique(false); index.setNamespace(table.getNamespace()); } columnNameList = SimpleIdentifierCommaList() { int iOrdinal = 0; Iterator columnNameIter = columnNameList.iterator(); while (columnNameIter.hasNext()) { String columnName = ((SqlIdentifier) columnNameIter.next()).getSimple(); CwmColumn column = farragoParser.getStmtValidator().findColumn( table,columnName); FemLocalIndexColumn indexColumn = getRepos().newFemLocalIndexColumn(); indexColumn.setName(columnName); indexColumn.setAscending(Boolean.TRUE); indexColumn.setFeature(column); indexColumn.setIndex(index); indexColumn.setOrdinal(iOrdinal++); } return index; } } FemUser UserDefinition() : { FemUser user; SqlIdentifier userName; SqlNode expr; CwmNamespace defaultNamespace; } { { user = getRepos().newFemUser(); } userName = SimpleIdentifier() { // set the repos name attribute user.setName(userName.getSimple()); } expr = Expression(ExprContext.ACCEPT_NONQUERY) { // TODO: Finalize the syntax for JAAS integration // user.setAuthenticationMethod = // TODO: validate and save the authentication method } [ ( defaultNamespace = CatalogReference() | defaultNamespace = SchemaReference() ) { // Set the default namespace for the user. The session default will // be this name space when the user logs on user.setDefaultNamespace(defaultNamespace); } ] { return user; } } FemRole RoleDefinition() : { FemRole role; SqlIdentifier roleName; SqlIdentifier grantor; } { { role = getRepos().newFemRole(); } roleName = SimpleIdentifier() { // set the repos name attribute role.setName(roleName.getSimple()); } [ grantor = SimpleIdentifier() { // Create a grant to represent an inheritant of this role and make the // grantor specified in this statement as the grantee of that grant. FemGrant grant = FarragoCatalogUtil.newElementGrant( getRepos(), farragoParser.getStmtValidator().getSession() .getSessionVariables().currentUserName, grantor.getSimple(), role); // set grant properties to reflect inheritant with admin capability grant.setAction(PrivilegedActionEnum.INHERIT_ROLE.toString()); grant.setWithGrantOption(true); } ] { return role; } } FemLabel LabelDefinition() : { FemLabel label; SqlIdentifier labelName; SqlIdentifier parentLabel; } {
table = TableIdentifier() CascadeOption() { return table; } } CwmModelElement ViewDrop() : { CwmModelElement view; } { view = ViewReference() CascadeOption() { return view; } } CwmModelElement RoutineDrop() : { CwmModelElement routine; } { routine = RoutineReference() CascadeOption() { return routine; } } CwmModelElement UserDefinedTypeDrop() : { SqlIdentifier typeName; CwmModelElement typeDef; } { typeName = CompoundIdentifier3() { typeDef = farragoParser.getStmtValidator().findSchemaObject( typeName, FemUserDefinedType.class); } CascadeOption() { return typeDef; } } CwmModelElement UserDefinedOrderingDrop() : { SqlIdentifier typeName; CwmModelElement orderingDef; } { typeName = CompoundIdentifier3() { FemUserDefinedType typeDef = farragoParser.getStmtValidator().findSchemaObject( typeName, FemUserDefinedType.class); if (typeDef.getOrdering().isEmpty()) { throw FarragoResource.instance().ValidatorNoOrdering.ex( getRepos().getLocalizedObjectName( typeDef)); } orderingDef = (CwmModelElement) typeDef.getOrdering().iterator().next(); } CascadeOption() { return orderingDef; } } CwmModelElement JarDrop() : { SqlIdentifier qualifiedJarName; SqlLiteral deploymentState; } { qualifiedJarName = CompoundIdentifier3() deploymentState = NumericLiteral() CascadeOption() { FemJar jar = farragoParser.getStmtValidator().findSchemaObject( qualifiedJarName, FemJar.class); jar.setDeploymentState(deploymentState.intValue(true)); return jar; } } CwmModelElement IndexDrop() : { SqlIdentifier qualifiedIndexName; } { qualifiedIndexName = CompoundIdentifier3() { return farragoParser.getStmtValidator().findSchemaObject( qualifiedIndexName, FemLocalIndex.class); } } void CascadeOption() : { } { [ ( { dropRestrict = true; } | { dropRestrict = false; } ) ] } DdlStmt SystemParamAssignment() : { SqlIdentifier paramName; SqlLiteral paramValue; } { paramName = SimpleIdentifier() paramValue = SystemParamValue() { return new DdlSetSystemParamStmt( paramName.getSimple(),paramValue); } } DdlStmt SessionParamAssignment() : { SqlIdentifier paramName; SqlLiteral paramValue; } { paramName = SimpleIdentifier() paramValue = SystemParamValue() { return new DdlSetSessionParamStmt( paramName.getSimple(),paramValue); } } DdlStmt CatalogExtension() : { SqlIdentifier jarName; } { jarName = CompoundIdentifier3() { return new DdlExtendCatalogStmt(jarName); } } DdlStmt CatalogReplace() : { } { { return new DdlReplaceCatalogStmt(); } } DdlStmt DeallocateOld() : { } { { return new DdlDeallocateOldStmt(); } } DdlStmt SessionImplementation() : { SqlIdentifier jarName = null; } { ( jarName = CompoundIdentifier3() | ) { return new DdlSetSessionImplementationStmt(jarName, false); } | jarName = CompoundIdentifier3() { return new DdlSetSessionImplementationStmt(jarName, true); } } DdlStmt AlterTableStmt() : { DdlStmt ddlStmt; CwmTable table; } { table = TableIdentifier() ( [ ] ddlStmt = AddColumnStmt(table) { return ddlStmt; } | ddlStmt = AlterColumnStmt(table) { return ddlStmt; } | { return new DdlRebuildTableStmt(table); } ) } DdlStmt AddColumnStmt(CwmTable table) : { DdlStmt ddlStmt; CwmColumn column; } { // NOTE jvs 4-Dec-2008: It's important that we construct // ddlStmt BEFORE parsing the actual column definition. // The reason is that the constructor for // DdlAlterTableStructureStmt needs to make a copy // of the unmodified table structure. { FarragoSession session = farragoParser.getDdlValidator().getInvokingSession(); ddlStmt = new DdlAlterTableStructureStmt( getRepos(), table); } column = ColumnDefinition(table) { boolean constraints = false; UniqueFeature uf = getRepos().getKeysIndexesPackage().getUniqueFeature(); if (!uf.getUniqueKey(column).isEmpty()) { constraints = true; } if (constraints) { // TODO jvs 4-Dec-2008: This is supposed to work; we just // haven't added the necessary support yet. throw Util.needToImplement( "Adding keys via ALTER TABLE is not yet supported"); } return ddlStmt; } } DdlStmt AlterColumnStmt(CwmTable table) : { DdlStmt ddlStmt; CwmColumn column; } { column = ColumnIdentifier(table) ddlStmt = AlterIdentityColumnStmt(column) { return ddlStmt; } } DdlStmt AlterIdentityColumnStmt(CwmColumn column) : { DdlStmt ddlStmt; FarragoSequenceOptions opts; SqlLiteral value; } { { opts = new FarragoSequenceOptions(column.getName()); } ( value = NumericLiteral() { opts.setStart(value.longValue(true)); } | BasicSequenceOption(opts) )+ { ddlStmt = new DdlAlterIdentityColumnStmt(column, opts); return ddlStmt; } } SqlLiteral SystemParamValue() : { SqlLiteral paramValue; SqlParserPos pos = null; } { ( paramValue = StrictLiteral() | { // TODO jvs 22-May-2004: for MIN and MAX here, use metadata // to determine the correct min and max values pos = getPos(); paramValue = SqlLiteral.createExactNumeric("-1", pos); } | { pos = getPos(); paramValue = SqlLiteral.createExactNumeric("0", pos); } ) { return paramValue; } } DdlStmt Rollback() : { SqlIdentifier savepointName = null; } { [ savepointName = SimpleIdentifier() ] { if (savepointName != null) { return new DdlRollbackStmt(savepointName.getSimple()); } else { return new DdlRollbackStmt(null); } } } DdlStmt Savepoint() : { SqlIdentifier savepointName = null; } { savepointName = SimpleIdentifier() { return new DdlSavepointStmt(savepointName.getSimple()); } } DdlStmt ReleaseSavepoint() : { SqlIdentifier savepointName = null; } { savepointName = SimpleIdentifier() { return new DdlReleaseSavepointStmt(savepointName.getSimple()); } } FemDataWrapper DataWrapperDefinition() : { FemDataWrapper wrapper; SqlIdentifier wrapperName; String libraryFile; boolean isForeign; } { isForeign = ForeignOpt() wrapperName = SimpleIdentifier() { wrapper = getRepos().newFemDataWrapper(); wrapper.setName(wrapperName.getSimple()); wrapper.setNamespace( getRepos().getCatalog( FarragoCatalogInit.SYSBOOT_CATALOG_NAME)); wrapper.setForeign(isForeign); } libraryFile = QuotedString() { wrapper.setLibraryFile(libraryFile); } { wrapper.setLanguage("JAVA"); } OptionalStorageOptions(wrapper) OptionalDescription(wrapper) { return wrapper; } } boolean ForeignOpt() : { } { { return false; } | { return true; } } FemDataWrapper DataWrapperReference() : { SqlIdentifier name; boolean isForeign; } { isForeign = ForeignOpt() name = SimpleIdentifier() { return farragoParser.getStmtValidator().findDataWrapper( name,isForeign); } } FemDataServer DataServerDefinition() : { FemDataServer server; FemDataWrapper wrapper; SqlIdentifier serverName; String serverType; String serverVersion; } { serverName = SimpleIdentifier() { server = getRepos().newFemDataServer(); server.setName(serverName.getSimple()); server.setNamespace( getRepos().getCatalog( FarragoCatalogInit.SYSBOOT_CATALOG_NAME)); } [ serverType = QuotedString() { server.setType(serverType); } ] [ serverVersion = QuotedString() { server.setVersion(serverVersion); } ] wrapper = DataWrapperReference() { server.setWrapper(wrapper); } OptionalStorageOptions(server) OptionalDescription(server) { return server; } } FemRoutine FunctionDefinition() : { FemRoutine function; SqlIdentifier qualifiedName; } { { function = getRepos().newFemRoutine(); function.setType(ProcedureTypeEnum.FUNCTION); function.setCalledOnNullInput(true); } qualifiedName = CompoundIdentifier3() { // REVIEW jvs 27-Dec-2004: SQL standard says that // specific name is implementation-defined when unspecified. // The behavior here is to use the invocation name, which // means if there's a conflict with an existing specific name, // the CREATE statement will fail. This forces users to // provide specific names when overloads are defined. An // alternative is to generate unique specific names automatically // in case of conflict. farragoParser.getDdlValidator().setSchemaObjectName( function,qualifiedName); function.setInvocationName(function.getName()); } [ RoutineParamList(function) ] ReturnsClause(function) RoutineCharacteristics(function) [ ] { function.setStaticDispatch(true); } ( SqlFunctionBody(function) | ExternalRoutineBody(function) ) { FarragoCatalogUtil.setRoutineSpecification( getRepos(), function, null); return function; } } FemRoutine ConstructorDefinition() : { FemRoutine method; SqlIdentifier constructorName; SqlIdentifier typeName; // TODO jvs 26-Feb-2005: support silly RETURNS clause and // method reference by invocation name and parameters SqlParserPos defStart, defEnd; } { constructorName = CompoundIdentifier3() { method = farragoParser.getStmtValidator().findSchemaObject( constructorName, FemRoutine.class); } typeName = CompoundIdentifier3() { // TODO jvs 26-Feb-2005: cross-check } RightsClause(method) { defStart = getEndPos(); } PsmBody() { defEnd = getEndPos(); String bodyText = farragoParser.getSubstring(defStart, defEnd); CwmProcedureExpression procedureExpr = method.getBody(); procedureExpr.setLanguage("SQL"); bodyText = farragoParser.getDdlValidator().setParserOffset( method, defStart, bodyText); procedureExpr.setBody(bodyText); // NOTE: this is necessary to force a revalidation of the method method.setBody(procedureExpr); } { return method; } } SqlNode PsmBody() : { // TODO jvs 26-Feb-2005: once we implement SQL/PSM, this should // accept any statement list; right now this is all special-cased // for UDT constructors SqlNodeList list = new SqlNodeList(getPos()); SqlNode stmt; } { ( stmt = ConstructorAssignment() { list.add(stmt); } ) * { return list; } } SqlNode ConstructorAssignment() : { SqlIdentifier attributeName; SqlNode expr; } { attributeName = SimpleIdentifier() expr = Expression(ExprContext.ACCEPT_NONQUERY) { return opTab.equalsOperator.createCall( getPos(), attributeName, expr); } } void ReturnsClause(FemRoutine function) : { FemRoutineParameter returnParam = getRepos().newFemRoutineParameter(); returnParam.setName("RETURN"); returnParam.setKind(ParameterDirectionKindEnum.PDK_RETURN); function.getParameter().add(returnParam); } { (
TableFunctionColumnListElement(function) ( TableFunctionColumnListElement(function))* { // TODO jvs 8-Jan-2006: should be MULTISET of ROW(x, y, z) returnParam.setType( farragoParser.getStmtValidator().findSqldataType( new SqlIdentifier( SqlTypeName.INTEGER.name(), SqlParserPos.ZERO))); } | TypedElement(returnParam) { } ) { } } void TableFunctionColumnListElement(FemRoutine function) : { FemViewColumn column = getRepos().newFemViewColumn(); SqlIdentifier inputCursorName; } { LOOKAHEAD(2) BasicColumnDefinition(function, column) { } | inputCursorName = SimpleIdentifier() { farragoParser.getDdlValidator().setSqlDefinition( column, new SqlIdentifier("CURSOR", getPos())); function.getFeature().add(column); column.setName(inputCursorName.getSimple()); } } FemRoutine ProcedureDefinition() : { FemRoutine procedure; SqlIdentifier qualifiedName; } { { procedure = getRepos().newFemRoutine(); procedure.setCalledOnNullInput(true); } qualifiedName = CompoundIdentifier3() { // REVIEW jvs 18-Jan-2005: see corresponding comment // in FunctionDefinition(). farragoParser.getDdlValidator().setSchemaObjectName( procedure,qualifiedName); procedure.setInvocationName(procedure.getName()); } [ RoutineParamList(procedure) ] RoutineCharacteristics(procedure) { // TODO jvs 18-Jan-2005: disallow characteristics which // don't apply to procedures } ( ExternalRoutineBody(procedure) ) { FarragoCatalogUtil.setRoutineSpecification( getRepos(), procedure, null); procedure.setType(ProcedureTypeEnum.PROCEDURE); return procedure; } } void SqlFunctionBody(FemRoutine routine) : { SqlNode expr; SqlParserPos defStart, defEnd; } { RightsClause(routine) { defStart = getEndPos(); // TODO jvs 24-Dec-2004: eventually allow subqueries and // non-functional routine bodies. } expr = Expression(ExprContext.ACCEPT_NONQUERY) { defEnd = getEndPos(); String bodyText = farragoParser.getSubstring(defStart, defEnd); CwmProcedureExpression procedureExpr = getRepos().newCwmProcedureExpression(); procedureExpr.setLanguage("SQL"); bodyText = farragoParser.getDdlValidator().setParserOffset( routine, defStart, bodyText); procedureExpr.setBody( FarragoUserDefinedRoutine.addReturnPrefix(bodyText)); routine.setBody(procedureExpr); } } void RightsClause(FemRoutine routine) : { } { [ ( { routine.setImpersonateDefiner(false); } | { routine.setImpersonateDefiner(true); } ) ] } void ExternalRoutineBody(FemRoutine routine) : { String name; } { ( name = Identifier() | name = QuotedString() ) { routine.setExternalName(name); } [ RoutineParameterStyle(routine) ] [ ( { routine.setImpersonateDefiner(true); } | { routine.setImpersonateDefiner(false); } | { routine.setImpersonateDefiner(true); } ) ] } void RoutineParameterStyle(FemRoutine routine) : { } {

Farrago Developer FAQ


This page has been relocated to the Farrago wiki. eigenbase-farrago-0.9.0/doc/lurql.html0000444000175000017500000004512511173714170017556 0ustar drazzibdrazzib LURQL

LURQL

LURQL is a specialized language for querying metadata via JMI. As input, a LURQL query takes a JMI object extent and its corresponding metamodel, and as output produces references to the JMI objects which match the query specification. LURQL has several special features which make it the right tool for the job:
  • Metamodel-guided query evaluation. This makes it possible to express a very generic query such as "retrieve all of the composite parts of object O as well as any objects which refer to them" and apply it to an object of any type. Before execution, the query processor will automatically filter the metamodel to find the relevant composite associations. This also means that if the metamodel later changes, the query definition does not need to be modified; new associations will be traversed automatically as appropriate.
  • Recursion. This makes it possible to express queries such as "retrieve a definition for view V as well as all of the objects it depends on, recursively expanding the definitions for other views and user-defined functions encountered along the way."
  • Understanding of class hierarchies and associations. This means that if "materialized view" is a subclass of "view" in the model being queried in the previous example, the query will work for materialized views as well, and in addition will pick up any additional dependencies such as the storage or triggers used to maintain the materialization. Further, LURQL has no trouble dealing with heterogeneous intermediate and final result sets.
By contrast, SQL is excellent for querying relational data, but not for querying the complex object hierarchies and associations typical of metadata. (Recent additions of object types and recursive queries to SQL have improved the expressiveness, but optimizer technology hasn't caught up enough yet to make usage practical, and metamodel-guided evaluation is still completely lacking.) In the other corner, XQuery is good for semi-structured hierarchical data, and has some support for recursion, but is not appropriate for metadata (which has rich graph structure and a well-defined metamodel). However, a special-purpose language like LURQL is necessarily limited in what it can do, and there is much room for improvement.

This document presents the syntax and semantics of LURQL along with examples of how to use it. It assumes familiarity with UML.

Example Model

As our example metamodel, we use the Common Warehouse Metamodel (CWM), which defines standard relational objects such as Schema, Table, View, and Column using UML concepts such as Namespace, Class, and Attribute as a base. More details on Farrago's usage of this model are provided in the Farrago model documentation.

As sample metadata to be retrieved (instantiating the above metamodel), we use the standard Farrago example schema. Here's a UML object diagram for the partial definition of one of the tables (including its containers, columns, and their datatypes):

Simple Queries

Here's our first LURQL query, which finds a table by name together with all of its columns:

select * 
from class Table 
where name = 'DEPTS' 
then (
    follow association ClassifierFeature
);

EXECUTION RESULT:
LocalTable: DEPTS
StoredColumn: DEPTNO
StoredColumn: NAME
As you can see, LURQL uses a SQL-ish select/from/where structure, but the resemblance is only superficial. LURQL queries have a mapping to the directed graph structure of the metamodel of interest. In this case, we are starting from the extent of all tables, filtering down to just those tables whose name matches the string literal 'DEPTS', and then following the association ClassifierFeature to pick up the corresponding columns. The result set is a collection of JMI objects (one table and two columns); we only display the object types and names in this document, but the actual return value is a reference to the live object in the repository (from which all of its attributes and links are accessible). Note that the actual type returned for DEPTS (LocalTable) is a subtype of the requested CWM type (Table); LURQL automatically includes all subtypes in its search.

Unlike SQL, the * in the select clause does not project attributes; instead, it projects entire nodes of the query graph. For example, if we only wanted to retrieve the columns:


select c
from class Table as t where name='DEPTS' then (
    follow association ClassifierFeature as c
);

EXECUTION RESULT:
StoredColumn: DEPTNO
StoredColumn: NAME
The as clause can be used to apply a label to each from or follow clause. In this case the label "t" is unused and is only specified as a syntax example. For follow clauses, the label is applied to the set of classes reached via the association (or associations) traversed (StoredColumn for c).

Follow clauses can be chained to arbitrary depth. For example, to retrieve the schema and table containing column EMPNO:


select s, t
from class Column where name='EMPNO' then (
    follow association ClassifierFeature as t then (
        follow association ElementOwnership backward as s
    )
);

EXECUTION RESULT:
LocalSchema: SALES
LocalTable: EMPS
LocalTable: TEMPS
View: EMPSVIEW
View: TEMPSVIEW
Wait, where did those extra objects come from? It turns out that there are four different objects in schema SALES with columns named EMPNO: two tables (EMPS and TEMPS) and two views (EMPSVIEW and TEMPSVIEW). LURQL followed all of these paths from the root column object EMPNO, and then merged all of them at the single parent schema (duplicates are always removed from the final result set).

Note that the query above specified the backward qualifier on the traversal of association ElementOwnership, which is what takes us from table to containing schema. The reason is that the ElementOwnership association also links tables to other objects such as constraints and dependencies. LURQL imposes direction on the underlying metamodel as follows:

  • for a composite association, "forward" means "from container to contained"
  • otherwise, for a 1-to-many association, "forward" means "from one to many"
  • otherwise, for an ordered association, "forward" means "from non-ordered end to ordered end"
  • as a fallback, "forward" means "from first end to second end" (end assignment is somewhat arbitrary in many UML models, so this isn't guaranteed to be useful)
In this case, we happen to know that the only traversal we are interested in follows the backward direction. As contrast, here are the query results without the directional qualifier:

select s, t
from class Column where name='EMPNO' then (
    follow association ClassifierFeature as t then (
        follow association ElementOwnership as s
    )
);

EXECUTION RESULT:
Dependency: EMPS$DEP
Dependency: EMPSVIEW$DEP
Dependency: TEMPS$DEP
Dependency: TEMPSVIEW$DEP
LocalSchema: SALES
LocalTable: EMPS
LocalTable: TEMPS
PrimaryKeyConstraint: SYS$PRIMARY_KEY
PrimaryKeyConstraint: SYS$PRIMARY_KEY
UniqueKeyConstraint: SYS$UNIQUE_KEY$EMPID
View: EMPSVIEW
View: TEMPSVIEW
Direction is not the only qualifier available for filtering association traversals. The others are covered in some of the later examples as well as the formal syntax.

Divergence and Convergence

In the previous example, we saw how LURQL can follow many different links in parallel, all matching a single follow clause. It is also possible to explicitly specify more than one follow branching out from the same origin along different associations. For example, suppose we'd like to find the datatype and containing tables of a column:

select t, d
from class Column where name='CITY' then (
    follow destination class Table as t
    union
    follow destination class SQLDataType as d
);

EXECUTION RESULT:
LocalTable: EMPS
LocalTable: TEMPS
SQLSimpleType: VARCHAR
The keyword union is used because the final results are based on the two paths combined (with duplicates removed as always). Intersect and other set operations are not currently supported. The follow qualifier used here is based on the class (Table or SQLDataType) reached rather than the association. The destination qualifier means filter based on the class reached rather than the starting class (the origin qualifier provides this alternative).

The example above shows diverging paths; it is also possible for paths to converge and then carry on together. Suppose we'd like to query the union of the columns of view EMPSVIEW and table DEPTS in schema SALES:


select c
from class Schema where name='SALES' then (
    follow destination class Table where name='DEPTS' 
    union
    follow destination class View where name='EMPSVIEW'
) gather then (
    follow destination class Column as c
);

EXECUTION RESULT:
StoredColumn: DEPTNO
StoredColumn: NAME
ViewColumn: EMPNO
ViewColumn: NAME
The gather clause combines the leaves of the unioned paths and then applies the last then clause to that combination. Schematically:

In some cases, a query may need to contain excursions; the gather with parent variation can be used for this purpose. For example, suppose we want to query the columns of a view together with all columns of directly underlying tables:


select c, t
from class View where name='JOINVIEW' then (
    follow association ElementOwnership destination class Dependency then (
        follow destination end supplier destination class Table as t
    )
) gather with parent then (
    follow association ClassifierFeature as c
);

EXECUTION RESULT:
LocalTable: DEPTS
LocalTable: EMPS
StoredColumn: AGE
StoredColumn: CITY
StoredColumn: DEPTNO
StoredColumn: DEPTNO
StoredColumn: EMPID
StoredColumn: EMPNO
StoredColumn: GENDER
StoredColumn: MANAGER
StoredColumn: NAME
StoredColumn: NAME
StoredColumn: PUBLIC_KEY
StoredColumn: SLACKER
ViewColumn: DNAME
ViewColumn: ENAME
The first follow chain defines the view dependency traversal (and demonstrates association filtering via end names). It is an "excursion" in the sense that regardless of what it finds, we also want to include the original view (the "parent") as a source for the final follow after the gather with parent. Here's the corresponding query graph:

Recursion

The examples so far have contained query graphs which match the structure of the underlying metamodel exactly. If the structure is complex, this may be cumbersome (consider enumerating all of the parts of an object such as a table). And in some cases, the structure may be recursive, allowing chains of arbitrary depth. To address these requirements, LURQL provides recursion. Here's a simple example which expands all of the containers of a table:

select *
from class Table where name='TEMPS' then (
    recursively (
        follow composite backward
    )
);

EXECUTION RESULT:
LocalCatalog: LOCALDB
LocalSchema: SALES
LocalTable: TEMPS
The query did not mention any particular association or class other than Table; the structure was discovered automatically by query execution.

Recursion may contain follow chains (or diverging chains as long as they all eventually converge back to a single endpoint) and may be followed by more non-recursive query processing. Here's the previous view dependency example, this time capable of handling arbitrary depth (the results are not shown since the example views only have one level):


select c, t
from class View where name='JOINVIEW' then (
    recursively (
        follow association ElementOwnership destination class Dependency then (
            follow destination end supplier destination class ColumnSet as t
        )
    )
) gather with parent then (
    follow association ClassifierFeature as c
);
Note that the dependency destination has been changed from Table to ColumnSet (which includes the views we want to recursively expand). Such a recursive query can be diagrammed as a cyclic graph:

Existence Filters

So far we have seen how LURQL can navigate complex models, but the filtering performed during navigation has been very localized. LURQL supports an exists clause for filtering based on the existence of related objects.

Suppose we'd like to find all schemas which contain tables named 'EMPS':


select s
from class Schema as s where exists (
    follow association ElementOwnership destination class Table 
    where name='EMPS'
);

EXECUTION RESULT:
LocalSchema: SALES
By default, exists tests whether results are found for any node in the subquery (which can contain any kind of LURQL construct, including union and recursion). For more selective existence tests, it is possible to make the decision based on a select list. Suppose we'd like to find tables with columns of type BOOLEAN:

select t
from class Table as t where exists d in (
    follow association ClassifierFeature then (
        follow destination class SQLDataType as d
        where name='BOOLEAN'
    )
);

EXECUTION RESULT:
LocalTable: EMPS
LocalTable: TEMPS
If multiple variables are specified in the select list, then the existence test passes if any of them return at least one result. (Union rather than intersection.)

SQL Integration

At times it can be useful to complement LURQL with SQL. When properly configured, a LURQL query processor can use SQL queries as sources for filter lists. Here's an example of how to get the datatypes for all columns having a name ending with 'NO':

select dt
from class Column where mofId in
[select "mofId" from sys_cwm."Relational"."Column" where "name" like '%NO']
then (
    follow destination class SQLDataType as dt
);

EXECUTION RESULT:
SQLSimpleType: INTEGER
Any query text in between square brackets is not parsed by LURQL; it is instead sent to the configured SQL connection for execution. The SQL query should return a result set with exactly one column.

In this case, the SQL query is against the catalog views derived from the same metadata being queried by LURQL. The "mofId" column is a special internal column representing the JMI object ID.

API

TBD

Formal Grammar


<lurql-query> ::= 
select <select-list>
from <root>

select-list ::=
'*'
| 
<id> [, <id> ... ]

<root> ::=
<simple-root>
|
<compound-root>

<simple-root> ::=
class <id> [ as <id> ]
[ <where-clause> ]
[ then <path-spec> ]

<compound-root> ::=
'(' <root> [ union <root> ... ] ')'
[ gather then <path-spec> ]

<where-clause> ::=
where <filter> [ and <filter> ... ]

<filter> ::= [ NOT ] <leaf-filter>

<leaf-filter> ::=
<id> '=' <value>
|
<id> matches <regular-expression-value>
|
<id> in '(' <value> [, <value> ... ] ')'
|
<id> in '[' <sql-query-text> ']'
|
<id> in <dynamic-param>
|
exists [ <select-list> in ] <path-spec>

<value> ::=
<literal>
| <dynamic-param>

<regular-expression-value> ::= <value>

<dynamic-param> ::=
'?' <id>

<path-spec> ::=
<path-spec-without-gather> 
[ gather [ with parent ] then <path-spec> ]

<path-spec-without-gather> ::=
'(' <path-branch> [ union <path-branch> ... ] ')'

<path-branch> ::=
<follow>
|
<recursion>

<follow> ::=
follow [ <association-filter> ... ]
[ as <id> ]
[ <where-clause> ]
[ then <path-spec> ]

<association-filter> ::=
( origin | destination ) ( end | class ) <id>
| composite
| noncomposite
| association <id>
| forward
| backward

<recursion> ::=
recursively ( <path-spec-without-gather> | '(' <path-spec> ')' )
[ then <path-spec> ]

<id> ::= 
<double-quoted-id> 
| <unquoted-id>

<literal> ::=
<single-quoted-string>
| null
  • Unlike in SQL, identifiers are always case sensitive.
  • Identifiers only need to be quoted if they are keywords, contain non-alphanumeric characters, or start with a number.
  • All attribute comparison is currently string based; dynamic parameter values must be bound to either strings or sets of strings.
  • Unlike in SQL, there is no three-valued logic; the null literal can be used to test for null attributes via IN or equality predicates. It is not currently possible to pass null values via dynamic parameters.

Formal Semantics

TBD

Related Topics

For information on how to use LURQL queries to drive metadata visualization, see the DMV docs.

History and Credits

LURQL was originally developed in 1998 under the name BERQL by Roy Goldman, John Sichi, and others at Broadbase Software. BERQL was an acronym for Broadbase Entity Relationship Query Language, but there also happens to be a restaurant on Telegraph Avenue in Berkeley named Berkel Berkel. The original implementation of the language didn't have its own parser; instead, queries were phrased in XML (just like XQueryX), which was nice for machines but no so nice for humans.

In 2005, the code was contributed under GPL licensing to The Eigenbase Project via LucidEra, a startup which has acquired the rights to the Broadbase code. Besides rechristening as LURQL, major changes from BERQL include:

  • a human-friendly grammar and JavaCC parser
  • sourcing from standard JMI metadata instead of the proprietary Broadbase repository
  • support for execution of SQL queries to produce filter values
  • support for merging paths from different roots
  • new name, even more fun to say aloud
eigenbase-farrago-0.9.0/doc/lurqlDiagrams/0000755000175000017500000000000011173714170020333 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/doc/lurqlDiagrams/cwmExample.zuml0000444000175000017500000001470111173714170023347 0ustar drazzibdrazzibPK2cwmExample.proj3͙ݏ8Wccj^VpmՇBL┏1N\$JE 06o]lTۼ }iMpWTN3~~e&Pb㌔ugy9ku`Q쌨' byU  ~ H?c@8HbH!R ?bs?'b4~l.#8&#g?bs9@NH!Rq !!"+@8Y4"WN8aqUAV?ϓ%O!+idq͚gV}U=OջJ([Wt)a[W$a:@v02Gb UP \Dv`4d \Be (d \^a0 4bsOO1 4dsubz>lf9aE8$;0B\_b(@l.gP8C7=3)12p{4Hd/(NJf`2 8θ\ClɾN0_xS+-Je6J豭\fp0]67|ϓ˧$׹<5e[K|#Xݜ0%qdiw+2x]TcnHwx!y |!n[n6m#5\B#t;y^,R6\1@&9v !PKPn[PK2cwmExample.xmi][8~߈~˧39Uճ5Qy ;/6:/irtnOG?rmgYy7(#/? f׏~*5.ww_?~ d RpVxA6fwVRi=ܙ`?x_fizwEoQo,zZ ?l|Ww!F판<-E fk/?xͦ}}Q^c垕iLxNB+tMGv%x݌YXwtQѾc[[|2tK_|(>rJBt\mwK:TmaXaɖO͞mty itwai!^}g`ixke' 1>' Cq{}kyu2i((T[ie*!#+=RIJRZRgaWAR8ϒ SAH 1YLTٞ{cQDsiB^幚 OzF-Se}D_s/_,˟bhyz0SjPdF׊z&>+˴0j7Up7hN-g:L%pB8mUՖ,+֖UgFJj,+WHK$bvPAJ:Kg1ŴHh٣Sٚb%%R#(!*{7xu]K,)붒bT~HI#.cg䤯!XlP~[n@O$Z{bZ6~!a dӕndcl7µnJ!~9+nB@cJ'avbZ LW۳llfi)64WX6DСl=f.:ElIϲbrԯlrEv ؊o9!~e#jLX6NϲY+Ư}t!@X60]F6^{OKX60]i$6R` hvGYu %$+'>v?pmx7i;yS Qd۔ݡZA^X=-wbQRXc QgfSFNHee^u}9)cUyl^T1_ɭr,Y*|WޠS9ոb-x+fil=l t>-E% 4j&X]s+SfZ8 WSJM岡Ł0 @.// QɍT^^UJSG|,%t9K# ;L 25'Ly.݈3qpޘD(deIEdg%58^$]LCZ$EA۔(".)U,yH'gfS1XgN0R qܑ~M7YVO˹^<#}¥>Y`>Tj-bCC:Юꢊ{uU^, =:smU,Оi Qi\:X,|ST*e&gAu4=#:4k ~ Cľ%蒚e>~DovsI>E"a$!.(/8u EMw*iV[ך-LP0ܦ,S?{P7re_5VmK W;qn4ꂯR =Z[N=/|"i+J8}BOaxS\oa`w݇QGh7N*kEqϙΨdE7()L%ڔL Dk#m[QLVVTa ehs3S"o'OE/'O.ڨA&A{rɖ9 jh0h;VZc^Owœh/Nئ@.ց@m]SqYN;P T |@%?gNqVCj BGW~QFDa>ڟvԙGꈙ#,gئ qM19վR1SmqMU6[B]TE&ۢ;\]߯RˎL!d6J QO *h5%! 6G1|әsaԱur䓭#{w_w`\uDg6̔IXgUreU˾-]!S'AN5iSȂM"WI/\[ \2i5ͦi|y-rm$e_ Sj?p6!Ye %&H` Jud-ʭ:h \1j0bʚ˩UI FñRNuv;@;5 8S ͯ02l{1 (p S r H5q"6?6j 5ee-sp2Wlm^P,(U4lcC9~}{~^Y>ّCh0έcL 5"^ NbsESWS:_sm2{*_7=õܚx!>Ǻڪ[6ۮ]O.؎&F('f =])"|@٩:#1|BO|QOD>aͭ|Bu7\iw Vh_Jڊ5Țd7̍k IR(a1a@+&dsZ|.%5)oA1%hOCl>B Z,rRWNV5 Q*z0zDI%9R˵4R yC @l%Cz55` \CMb? ǫ}.i06,kQ- MׄH|S %:t3\Q$oko/ɴ,tĉ+;׆յaARCʰjX@k(\fµB(\jd[Fĕlƅµl_`ctpmV~j?ڰlBõltpmhI6Xpc,̑$B`6$%Nꗊq   xG^66NGa3gVhownĺ_^J$t=a[PuG /Q?qDwpC) ߌQ_B Q x|J͹/FC3Ձy#C^(+D!mZ,|{&5n߫Q-:nӪ΃mZQ0֢smg՜ ce Ϩchc  r6FW( bݢ` c|B&LӕF1YK(`0 & Ʊ ˫s`ɗPa0w"~o~)i+ % #7[6M;h Ʋ&4 0WلiL5t0 ! "P&UC&13 Æ0fP(LuȐ' R)S毯q0&cu_K8C/ Jď54Ku2o \ f@iPyn@iPD'WFtL?K 1?a{/ Im-J-{hMi1я1$|ttmܚ7Qr\p&J4gvm0 6z l0L&Pڐ!kosXJo",ExnAicoa w+U\e0 oZ'~HF ;q<h[,|H&dj`*Л<^y ~K-I on 2T4)O@̡^ `]zNl.)F;'Odopj 'hSQ=Uap "c f @NfwdMs))draO7"\}ƳNhzqS4C`|,s}5 ˶k TG)0}(~vO9ZJP]`ؾ XIppbk ŸJX)μ2X)65Xioc +EJi|ӕFVdX)Q QpW˞MmanͻoGaM:#|Уkl.&سk~}Ë?R虖|fW AW lBZOy)R8^)pz)j?jݨ(k#ZFDk:߭.k˝wkҔ:z,V{ִE'\0|pM$¶IZ`@U-8 X"dvQYbKof;ZMlUvFw ,$l(,0lWȨ\@*ό I3ԥHu rJ9BH%Gμ: A 1p@LB՚ʹAUe ؄,v;ޛctxxGnoywnyvG4IzD&ŕ駳:XmpM U,, A3<52 0 V@Pt38p\&ҵBmh|5R Q&8sQ@p `?`͓x 6( `)$Z T<\n⟋ҴE.q~8J^+"~8̡k!ʈDLq&&*q"*dT)9+NAD`RD,na ( pTY&AoLӋB="eDL Q93D"*^|^XN%4STtݧX!EL*WV򕰌,gIZ̥.83|Y fLbicJH)FhŘDrg,# *@DzO Ҝ=IcCԋaQ(#_-HP adkR(Pe>3h@HF[%D΍P G;qִ-(Lw#Ri[}xJԔ4YEM<Ԧ~ၪSi)TujvUWr:_*:,,*en 'w9]j  ,YEuB~0JB'^]`U" W`o.F 6D@83 ™mNLП< \RAA0 ui*'ݤrEekbj%.IEiOaFeGD B$ATwK z 罨wnpԢ ƻ?24ъ_hdf3)Y,B_tD JqS/Gm},ADؕ@,sy5oaΛmt:\`jO(K-cpT<0 zق)GδakH!YtMB:/S"RF(Jx-KEMEODQXU8VYX;W8]``9_FcX_bxFjX8e/m9oHs?o@QcQ^}Oj8C5Wi$9tiU:X?35H"sUQwzDV3jtGy(LG1c))WR" )qwx;Lvh>؋-LU1!( 17A$C%<(0|30c1pCvW$0k-ӂ q} /&q'vh 'p$UAe,P#"@1`zz3n" %IQyyg1Sl8b>`GbV[ &ՒfFmX6W/a|J20_{!撆xdWw5R1[&~R0;‘G1"In#@g>7U(' iGOV*}a ZG}*8k'Gp7e[a 2ٗM%oT%drq {PY~U|A]NH-GF=e}jb9$dGQ Pa#0 eNGQ7G3PH)HrB.էG`@h.՛g>0+&Q6fRb JfF6#'Er!xWXxXm҈ċxdz='%NQ p.ՉNhmcԏ9<ɣУ3P}31&x1!` ɁJ XXvqHuC8+#8Kʥ]gi$0W*53A:lȇ{AH@⧇A֤ 3 6f2jzz33z z1ꩮ8 2,rRxEӉ„X~7Ѫ*(qZcXVj,`@VgTӊ2s5HH13@eHqn3k3֭LhcGz71@:1]w"U SZH꩕WQ2~2 Q3P#0 RqzPYNQGV([&%QQ"4P0E12ʲӰky96Y3SaY5-V"yF  0~9)T /eӵUT  &2i![;q1`GVZ&"J:R<XжvriDKۺh! STARDIV 5.0 t6;eigenbase-farrago-0.9.0/doc/lurqlDiagrams/recursion.gif0000444000175000017500000001167111173714170023037 0ustar drazzibdrazzibGIF89a!;,   $) -%3(7+;===.@1D5J8N ֫۷p;6ٻxIpF{`@U%4mC8 4Wݼ7NMjUS צ|GOՍ0b$pF$Ш;"p;6 qwZi6Z%Ѵ * خJ0lj}??Ԯuj 5V ,w M7`/T _ d8Д `^F[qU}$oh&x*(d.hLݨ@cD߈E&$JC.$GTV&6\e`edyb,kBG)'Hci'>ީ'Fu'P%UhvsхZ%m*iWsIH矜2Va@#L*颅 ;lJUVU y}iU2WHv,Vb0ר\BΆ@>,t:Tkյ٦,bւ_! ZUEj:iUQ_An+˟kXG_[|U˦lib:ɼJ@ p@,Ǭvi1 4CmͦL7M':ͧTWmXg\w`-dm_Z zl?*:vt_4`i\7@^`xU !@ 0,W]xCzZC! )XlVS=x^zpް@W=GB TAgB=@V@4$YTUY(@al|I_} |Y/\)蠊JݫTUվw}xocvϿP'@*C`1gy  H`2%Mx }&.ЖP 5|).SeX9 f80q{`!T&ys̄RYb8@AE ᠋^U4X=:@a0p @+|22V.\ɩ$wUQoػ4ȑ^,[rHQN[:+usVز>ՍKLDc%\.>gȤ L&LY ^)A5Ff|n7iL:IMr~ @z=PKITYІ$r:sd9 jQeo* Vr pTEPu"r#D׽R2h S֐ J B%FXev. rT,ᔠ*.PHu%jR V슬bH(,s:TCF,AU FUP*AȹIȍmT &%S2! y4qZתFf\Ӷڕ ȧ9 J#SV;ڄB+c0 HI P g va6x銼 O˪wjoߛҗ|}ߒTpQ$-' J:0<+I0_awOp?ܢ/$KSl%i.ZH_6Fr#ط>fM"Ƞ)*!Љ6Nrf@% Xr6*dHH u2*-氈%'s RJ:/m oB+C7";Hw10@[ E!EH57Xs,guX( V`P UԢ&p@`ӝ1KCZ7εp@,K|iyڊ VGn L`  9TH&A lp@T|@Ԛa:uҋ9ЧIWw(I)i!=`Mͅ˜`٠H^4|_kr"37$( 3b (9}4m5EPc( 1Á°븺WT>U|c8;4`\qF]B 1N|QjE7FZ;׫wĺ]oJ@,@VW`++|:v7mYUpl|Pnh.i1S0{-~wNʧ_/5kԷ,OOOϿHO_W(eev{jր[ ~tPef Pۇ@he7V'h( %T,؂1nIs6W-%O >D DDFh}TDf}qYYa;2hLbAP\hby=ń/eiq.2` ` XQzrXn!ssss%V9vÄ# -*!.WA,x4h700X[v 0qz"Vd6 `_x`tsu7h{ hwxx#ygyyuoy(GrD)##JY^rLALc)ZLt2O)”3spy{G E{I'|/U});م'+G)&G映9aq5)z!f "t䛷'i̩ й49Y,~iOOiOyO YO ~)}5V~iɟyi~*pI ꠉf Jܙ}w$KƗ 7&*ڐ dfP6yArCL/SRFQ)*,Cdb)v@BjdBz(HJ1 –;#R}F HC1bKJ"P_f)!2pA'sC[F:LS999o%1 7,TI1CC"7 v 1SzM UQmHX!fT*O$,ZqA!DH$MWUI55QW!cTF=QǑѪ 7nYl03cZs9MTMGP0F8UvL,u%Ўx  xu<2ZU; bCdo΂VhjqYtn%WSs5FVqWK_*c#{%;, 4)eUQC!V9P,SZ:bQZÓ +Z7pW6 Vu<cq2395;?iWۣ8*(0Pu1]$ZX!!QKIK{I7 ! -I85M 3Yqr[s /Q˵Seȸ7V(ne!!qȫkʫ8!\|97[(ȅg6G[FMp B   ;t!h!!\21;bup{}q$K͔e[zhȡծݓ35pP #\Xm Bם%\ĕǵ>5FU1]Յڑ]/]QRy<X$Vw BF)r>Pp!jg\(v>wL~b89ӥU0tqw1}la{eB <[<#p4`%'BUBb7E^36_ʰ\)},},˽' <\,љȬ̾\\|1! STARDIV 5.0 t6;eigenbase-farrago-0.9.0/doc/lurqlDiagrams/cwmExampleMetadata.png0000444000175000017500000003544111173714170024611 0ustar drazzibdrazzibPNG  IHDRb}L IDATx{Pga-Zb`p0?Ch$`7Vd$j+1ͭvsnnZkDdWY \@ĝV͊(gt{pyyo?3|xz ظ@1:ALb"tD &@Gpe0= D# c#D &@1:ALb"MJl>~jAvp_~ƍzzz\Goppb)//W;Pȑ# 7oޑ#GT#w ?"%;rnc7EQ,..NLLqsѤ$ս&I[Nņbھ`| &%L&Ӷm֭[׿omXz~ܸqY[[+ݔgFkה-׬Yo 0{M6]V\6:: .---}衇yeӧ~OVU>{lt{{3ӧwX ( %(fEQ ڛAxtZ Mjr5ǏWVx<7t_r%!!!??ҥKRY|||AAKKKSuOMM<|LL%;;رc(:t(;;GYoմ5h 6}Sk>qVWW'$$TUUV}UNwAuFKIWK[*++KŴJeUFٳgĜ:u*22OΝ{1S: ޮbw}ͻᄏL;VYշCBB륨z oϝ;w .u]X (@L0ڬ]vʕnO֬Y'O~{1{[ZZ""" 69sF 6{;777##CuEGE{_]x}͚5G_w¼<` 6xk,o߾UV!Bllɓ'fGZF1&&F:[eU_}(&$$TVVfeenUumڴnxZ:;;###_j5\QVÓ0߲JKK߭Yfx_;vlܸq eG 3C?(0Q#8# &@1:ALb"tD &@1:ALb"tD &@1:=!XaE1c*6lعsb1 d2z\z)XGp9b"`еIܹs&Iʋqqqqqq| FPǪn-...!!AZ&8DL 555MMMB{{tl6Ϛ5jG`(ÔkkkAL&b5klc ZDܬqAn#npZҵxfl0U1<<\ʋs5/8ALf555MMM555R^Hptc68FDD(S#T1#hZF+b"!G%V.фttt( 鈉 #F4b"C@ {b"Ë28\FA䇪1 w҂@p#&01G1щ"&|ʕuuu O"? rhƦnZCCC3f~ &\v]qLLJMDssscccMMMSSApd\F2T ׯ˓jSNX,'ۤ寿z޼yMUwm{UM`0n喯7={l*+uڂ*3f̐Ow ]__?}oކ{&)==^ڽ{wyy׏?jժիWO++jGFFJr˖-R"8 ;w&&& ?>ު:+44CY[wC{gΝT åު 檪Ɔ1gΜsL'p@0vd4i˗'OmGl6A.]?(k۫\|9**/ QE9EЧh z{_|Q^p8+777##Od2L5tcssnwMMMz+d6ҁw}'T+//裏^z믿xC=T^^x}٦Mv yyył;v4iR^^u+iڂӢtWW׌3 \c;?OV^}뭷6 I7f S;vظqf䆭;Ѫ7.0 /<5Ǐ`0c6qa6DLb"t`0 Ӫ2e9s?~ܠG٬|ȑy慄̛7ȑ#qr)?Ryp_~ƍzzzz/{~@nWVWW'&&\.o5رc pw^rEuoqqqbbb]]( IIIŪML&嚛n'Hk08 ٸqgϞd2m۶mݺuk֬yA={[ofuFڵkMpu?s熄̝;WYANZ__oXϞ=k6+**{[ZZΝ;w܊Hi+oX,u+]>}… sssKKKzwyGnv뭷666>><> эʕh4UAE^8/~ oevAyh~Qޖvr%''_lٮ]DQܳgϲeˤ6m۶mn[H>[l*L&ݑ}+W$$$_tIl6֭[/\:yd{%tsV8q4m,M͟?˖-8qnY3g~O>D744ڵkƍnK&++kΝr &ttth 7n6* G"]_!Jo:;;{{n!PZZz]whٳgĜ:uJ>;wܲfYYU,Kqq̙3|׆୷ުM9Mnzoz™o޺hG{ XFLuk׮)//QQQ_~eXX˗孷ztoh"ѧAjhG5i$yxaaa---/^͵l@0O 0_///x<¿}T>۴in!//X߲eKJJA;v4iR^^U z]*++{'A(//裏^z믿֖uuuDGG7M`]t۹sgxxxFFFVV֔)S=( p86o\UUG9f466nݺsYrezzzhhha6_[[ہֶrʺ@ l"賮{:%KXjzP3b"ƽ{8pl6Xbɒ%\8 z&\vݿկ"##=( .fW+V34&-]022rŊ q{VUUegg@ l"Ap\{̙ù)M`s޽{AXbEuu5@BL`,.8qGٽ{7> [970֖w˗sn |c6LXp!>D_{'NbŊ˗sn &U:::8}̏>sS?&0JpCl\DF?XUGydŊ\asSn+Wrp mmmػw^|yqq1>Ġb6tn߾0== bsSU= =`x8|޽{ :tf. >|nspGL .]߿?88>Laa۝N%KV\Ʌ1j҅c2>İ7".]~7ܹs҅=(+ft%%%?|fm D˹sMZjUfffDDDv‡.kӟ̙åm00߸\VuŊ霛l(ܹ}n Ff觮.ñw'Nfdd,\5YMMc6~ᬬ,.c?zKyn-ЃKaȆ`7Px- v`gկ.\ȅ1y>sO`Y yX3.pDL ?&ґ#G͛2o޼#G Fu&GF7Wp (1A&Lp5fIIٳ'..̙3/CBBRSSrH2 z2vQٳf9::BZ} 斖>C.zkccOC۟CRSS+++ϟ?#ϿrJBBB~~Kn&e5mͶu .N8}t?Yf){=zj `Z#eMMMӦM/DQ~{ݮ N[BBBBeeeVVVNN}}M&SSSjemߥ|lu|lο1}{v[\x;սLLz?1199Y~/EO?MNNEj*+թ|}|8q"11QuW~~U j7߼꫏=ѣGj7>]fΜ硯RK6+i>UVqi֬YQQQ򚨨 l۶t.]TcPa>=+r}{+;{vUWW9sLiTE{+i˜N DQ?tF{ҋ?22ҥK=oٲeI{YlWt;⣋{CQUUUEFFnw>Q~z r;RmR>6=]Z9m_jq*j =>4O_ەoU^8/~ oexFj Wv= Gq`tOL=O:$||roUYʏjݤ7x<]rI@|w}vHǏ=1= UUU~Jh<]Z9mΫ104z\(&wuUex{rV9vrF7{WyLtl6˱^~ 0~^c^]o5wO1!!AIDAT!I @>|n)ߍK6u|_cahޮ|͌CW˝7|͹sAu9sF^xaݺu ]6''\x߾}>( ---Bmo|.ڜ7-r8y !oo3{n{$MnnnFFK_wr`"uV=O|&}Yj^ 'Oo+RU)qwiT}JCoU -WwwM!ޫcN8<+\E$t0D`C _{_?G@75=__Ey *yh8?7y^ M؟h9&"̫v@&$9'0 |aq0D &@1:ALb"tD &@1:ALb"t`0 8Fg=2102lذ!//^pa\\\ .b"r_RRl322v{hhh18w\IIΝ;̙e2=.o H[[ۉ'>?<eʔ@ -b"t\.v}ve"&0D:::GiilooGRRRl6[xxx &nUUU6M'JcX!&HNNS ʵpDƒX,t(DuB)F1a)F 1)F 1b"#j1---33)F1Lb,**:p v]S8b"Dsstm#h#h###z#| &A`D#)ƴ%K08WcQQQaabIII4́1LbJwtt08@08F@?V?pBGb"'N啔ŋΙ3'B?K'J;%Kw}'N 7D0XGQQQIII2+3CďO8T(xo<~xaa0YoIIK/t)Q{_`0L!Pu%%%oonXr.$$m„ }տMO0ڵk}548\7P͛7߿ǎڛxDQE;*]2b"`[vmNNNyy/_/._,X,o /{ӷE9> RE;I& kiixbnnf0l6?~\CxbxxxKK}tttii.S*//;BYp_~ƍ>tjo* ?Z[[׭[i&ݮW쭋vT~Y{O ~,NLN7L&˕mW'^IRRҞ={>sQ^zo53gT7L瓒FcRRV?KHH jjj5kVTTo\.Wddj$(_DTTTmm mt:.]ӦMϳWZ%I1 :o(eӹ`Qϟ1OӦUVo655M2E.HJNN̲ev%={-[&l۶mR]jjjeecbb{-[HM&h4J_Tѭ;&_r%!!!??ҥKOͶu .N<۳v3g<ӟ|旿ŋ,Y9rObLKK;~UjjjvܙjzڵquwwO0C@u>E>![Nʗ>^MzƏ@={vLL̩S"##Avڇ~go߾]36YYYO? z R\\8ڵkW\vAطo߳>+|ꩧۧllٲ/?iYyJҥK{=Av޽xbmG੩_oܸk.,roߛ_GэʕEEE +IIIkkk_S]'O(O wVh4ZV)&ҹ5111ʳE/t킏e+&Aǯ Fs`"81@1:ALb"tD &@1:ALb"tD &@1:1`0z(Ν;WRR?{饗= 1S{{(((())JOO_`Ajj)S=4 1 TWW׹s>\PPPUUe6thZHEL\RRRPPt:L"G@ ~@L}rNm6}#vmzt:>a322v{hhhBLTV5###==d2zh D#̴4XCL%Kv&2b"c4qxAiXh!$DiⰨ]]])))LB O\."EC 1QK9q(nOIIYd Fovѣf9l"v_cM`SM?~Q&00ql"#b&0|I,,,8"&0477|t !Fb"r KKKl6ۂ RSSUe,Dv:Ή'l@ b"'t:KKKm6[JJn7F6b"}&n^ii0Lv]J'N !&+[[[v}ݷdɒ@ D|&j/^dɒ)Szh!&nwaa'|RXXam61ĉ|&Q^|ʕuuu \? rhƦoCLE%%%Nd2Ʃ3f(**5&LvZ ؏ 0{z=HGGGII/w奤|o… ~9Ѩ UԩS-tP[9&- nk۫j p-|WٳgfstttEE\VYTioo1c=}Nӧ~O6< :Q/ضm… CCCo7?9v\'f۶m%-?ʾmT˪(^t)11QRRSS+++ϟ?\Чx+옝}1Q:-/((xު:+44CY[wC&U ,͛SRRzsk׮_HVu=ܳs̿o]]]>a\F§~zƌmmmFFǏ6-QiyҤI/_mr\&ҥK?Ceewm{˗/GEE}aaa6h"B-^|EyM||S5ׯKMM}Gr?vw}'hll4j}իWW^}/^|衇=R]^U>۴in!//X9sǎ&M;~n> @[P~Z1c_|!z;?OV^}뭷CL.1wرqFy a ^x'|Rf H<&@1:ALb"t@ܹsϞ=+Fm_M|||~~+W/]$x<4UĨ-=Cegg(뭚&Qرc>(>۲:$| gGBPPPRR| uoRuuuBBBUUF}Dm_Mc4U+_ZE1--GYotxuר1s?|̙^SǏ-X@><}r…0i{Unt&''xʾ7|jjFclMMMwyުG ^ׯg{g7Чzj߾}'O~{1ڵksrr'kJKKKDDaÆ3gP__aVxݝwѢE"?s=/.j/ooL7|#LJJR\[[o߾UVI6-((H~TYF*{IyѣGVhNs[*}^&&$$TVVfeenUumڴnk322z[DSb07wk֬?q<|gqǎ7nH^]5pcpDNab"tD &@1:ALb"tD &@1:ALb"t#8a`0z0DQ 0p:ALb"tD &@1:ALb"tD &@1:ALb"tD &@1:ALb"t-VIENDB`eigenbase-farrago-0.9.0/doc/lurqlDiagrams/gatherWithParent.gif0000444000175000017500000001112311173714170024276 0ustar drazzibdrazzibGIF89a!:,   #) -%3(7*;===.@1E5J8Nf m `,ZaXj! Ʋ79 (ı.0K TPǬA ` XGp2t 8@%^i4RY#܌I7\rIbL2f:Ќ4IjZ̦6nz 8Ir\t))),)Y&x[V0E7e߂x~^Ҟ btr1x `/ڦBME  A $p:\(.ٛUfye BH+9Nl)[&7<&:-` Hd' Rӭ22 QR&J6$7 oH+ȷM҆vX-6`r ;P̬27.y}9D(AgN-QVR@.xGbkM4)EJALVdL-jf'0HcoD*m˓Dە}PU]nG AexoXF]}W'/^+`CP|y'6f ưM,⬕M$.gO,~ Rc<Ӹ)̻1otla<~@.rM۩9VJeUyuOͲܙ*$K @e(w¼l `E&S6s27S #hsЦ]¤+O<>^:YI{R\Kg0; j#fz,kJ` X sZ@^gـ Rd.rFP+T eIfՃJR|w4WPT5(`uOzkl9G5>6̫"#".< Zח__w6@م(P g? ?/r5/x{;t3! &P. @i\C8H $4)P6=(ALtnc~V/w!Bٖk $ZrgNPWfd&^sU88SYYj倢Cd(nWys%54}`5ctUKgjѱkuhi!`x$5hcQqdo7Bc5*`py*u񈲑0~ex{SqsU]rXxmMX` 5 PKz4KgCHÖH scz<2sQ?!( Kb7@( @ntdGxD*rHHi,rs8D۸3s}#[;,WRܨvդtsa 4t0&t *^ިaBGPvY>Xu7K>Fx-)b?uA)CuEYaxgw5 q NLٓS9ZUiWr[Yct%_'s7ccɕox[ ywluqnI&pYisx{L}wLwiLYwfIcbcɘx)d R{IMIdO觘 I)IvwÚpX2OY$^OgsAhH4z3f\v:t=+>GXOy5Dh>YՉZzI~1žnU"3q5E)Q2p$Eɡ{qqiCa$,`Aah'"xN#m, )ŝE94r*9,p87%:EV$epЂ6S9:f@jc c+7SE$pVi| @S1Bu[ƙYcJK9D%2PG,BbP$t*7aW\x[z67070dtu!70*J5]ڏx8"Ȇ$ej(U7b06`Fzm:'g+z:6X?0we!aQ(Yc-j"A(WI5> 8 *#%Y+ui(us7TcjU78h7 BU+(M?,pqQY{ҮZj3*6Z[jG2,0dA) 38|Z2Z4[c`.5A'ZI&;7Pd1Pu?6I˜rJ%IbCD&B G*C!ks[e{U  fc*^B&zERC57P5cyl b;[c'agwoe" p¡;"gdQ#/9t"jD!as_b[ ڻ۽;[{蛾(! STARDIV 5.0 t6;eigenbase-farrago-0.9.0/doc/stylesheet.css0000444000175000017500000001447711173714170020442 0ustar drazzibdrazzib/* // $Id: //open/dev/farrago/doc/stylesheet.css#2 $ // Style sheet. */ /*** COMMON ***/ A:link { color:#000066; } A:visited { color:#666666; } A.clsIncCpyRt, A.clsIncCpyRt:visited, P.clsIncCpyRt { font-weight:normal; font-size:75%; font-family:verdana,arial,helvetica,sans-serif; color:black; text-decoration:none; } A.clsLeftMenu, A.clsLeftMenu:visited { color:#000000; text-decoration:none; font-weight:bold; font-size:8pt; } A.clsBackTop, A.clsBackTop:visited { margin-top:10; margin-bottom:0; padding-bottom:0; font-size:75%; color:black; } A:hover, A.clsBackTop:hover, A.clsIncCpyRt:hover, A:active { color:blue; } A.clsGlossary { font-size:10pt; color:green; } BODY { font-size:80%; font-family:verdana,arial,helvetica,sans-serif; } BUTTON.clsShowme, BUTTON.clsShowme5 { font-weight:bold; font-size:11; font-family:arial; width:68; height:23; position:relative; top:2; background-color:#002F90; color:#FFFFFF; } DIV.clsBeta { font-weight:bold; color:red; } DIV.clsDocBody { margin-left:10px; margin-right:10px; } DIV.clsDocBody HR { margin-top:0; } DIV.clsDesFooter { margin:10px 10px 0px 223px; } DIV.clsFPfig { font-size:80%; } DIV.clsHi { padding-left:2em; text-indent:-2em } DIV.clsShowme { margin-bottom:.5em; margin-top:.5em; } H1{ font-size:145%; margin-top:1.25em; margin-bottom:0em; } H2 { font-size:135%; margin-top:1.25em; margin-bottom:.5em; } H3 { font-size:128%; margin-top:1em; margin-bottom:0em; } H4 { font-size:120%; margin-top:.8em; margin-bottom:0em; } H5 { font-size:110%; margin-top:.8em; margin-bottom:0em; } H6 { font-size:70%; margin-top:.6em; margin-bottom:0em; } HR.clsTransHR { position:relative; top:20; margin-bottom:15; } P.clsRef { font-weight:bold; margin-top:12pt; margin-bottom:0pt; } PRE { background:#EEEEEE; margin-top:1em; margin-bottom:1em; margin-left:0px; padding:5pt; } PRE.clsCode, CODE.clsText { font-family:'courier new',courier,serif; font-size:130%; } PRE.clsSyntax { font-family:verdana,arial,helvetica,sans-serif; font-size:120%; } SPAN.clsEntryText { line-height:12pt; font-size:8pt; } SPAN.clsHeading { color:#00319C; font-size:11pt; font-weight:bold; } SPAN.clsDefValue, TD.clsDefValue { font-weight:bold; font-family:'courier new' } SPAN.clsLiteral, TD.clsLiteral { font-family:'courier new'; } SPAN.clsRange, TD.clsRange { font-style:italic; } SPAN.clsShowme { width:100%; filter:dropshadow(color=#000000,OffX=2.5,OffY=2.5,Positive=1); position:relative; top:-8; } TABLE { font-size:100%; } TABLE.clsStd { background-color:#444; border:1; cellspacing:0; cellpadding:0; } TABLE.clsStd TH, BLOCKQUOTE TH { font-size:100%; text-align:left; vertical-align:top; background-color:#DDD; padding:2px; } TABLE.clsStd TD, BLOCKQUOTE TD { font-size:100%; vertical-align:top; background-color:#EEE; padding:2px; } TABLE.clsParamVls, TABLE.clsParamVls TD { padding-left:2pt; padding-right:2pt; } #TOC { visibility:hidden; } UL UL, OL UL { list-style-type:square; } .clsHide { display:none; } .clsShow { } .clsShowDiv { visibility:hidden; position:absolute; left:230px; top:140px; height:0px; width:170px; z-index:-1; } .#pBackTop { display:none; } #idTransDiv { position:relative; width:90%; top:20; filter:revealTrans(duration=1.0, transition=23); } /*** INDEX-SPECIFIC ***/ A.clsDisabled { text-decoration:none; color:black; cursor:text; } A.clsEnabled { cursor:auto; } SPAN.clsAccess { text-decoration:underline; } TABLE.clsIndex { font-size:100%; padding-left:2pt; padding-right:2pt; margin-top: 17pt; } TABLE.clsIndex TD { margin:3pt; background-color:#EEEEEE; } TR.clsEntry { vertical-align:top; } TABLE.clsIndex TD.clsLetters { background-color:#CCCCCC; text-align:center; } TD.clsMainHead { background-color:#FFFFFF; vertical-align:top; font-size:145%; font-weight:bold; margin-top:1.35em; margin-bottom:.5em; } UL.clsIndex { margin-left:20pt; margin-top:0pt; margin-bottom:5pt; } LI OL { padding-bottom: 1.5em } /*** GALLERY/TOOLS/SAMPLES ***/ FORM.clsSamples { margin-bottom:0; margin-top:0; } H1.clsSampH1 { font-size:145%; margin-top:.25em; margin-bottom:.25em; } H1.clsSampHead { margin-top:5px; margin-bottom:5px; font-size:24px; font-weight:bold; font-family:verdana,arial,helvetica,sans-serif; } H2.clsSampTitle { font-size:128%; margin-top:.2em; margin-bottom:0em; } TD.clsDemo { font-size:8pt; color:#00319C; text-decoration:underline; } .clsSampDnldMain { font-size:11px; font-family:verdana,arial,helvetica,sans-serif; } .clsShowDesc { cursor:hand; } A.clsTools { color:#0B3586; font-weight:bold; } H1.clsTools, H2.clsTools { color:#0B3586; margin-top:5px; } TD.clsToolsHome { font-size:9pt; line-height:15pt; } SPAN.clsToolsTitle { color:#00319C; font-size:11pt; font-weight:bold; text-decoration:none; } /*** DESIGN ***/ P.cat { font-size:13pt; color:#787800; text-decoration:none; margin-top:18px; } P.author { font-size:9pt; font-style:italic; line-height:13pt; margin-top:10px; } P.date { font-size:8pt; line-height:12px; margin-top:0px; color:#3366FF; } P.graph1 { line-height:13pt; margin-top:-10px; } P.col { line-height:13pt; margin-top:10px; margin-left:5px; } P.cal1 { text-decoration:none; margin-top:-10px; } P.cal2 {margin-top:-10px; } P.photo { font-size:8pt; } /*** DOCTOP ***/ #tblNavLinks A { color:black; text-decoration:none; font-family:verdana,arial,helvetica,sans-serif; } #lnkShowText, #lnkSyncText, #lnkSearchText, #lnkIndexText { font-size:8pt; font-weight:bold; } #lnkPrevText, #lnkNextText, #lnkUpText { font-size:7.5pt; font-weight:normal; } DIV.clsBucketBranch { margin-left:10px; margin-top:15px; margin-bottom:-10pt; font-style:italic; font-size:85%; } DIV.clsBucketBranch A, DIV.clsBucketBranch A:link, DIV.clsBucketBranch A:active, DIV.clsBucketBranch A:visited { text-decoration:none; color:black; } DIV.clsBucketBranch A:hover { color:blue; } /*** SDK, IE4 ONLY ***/ DIV.clsExpanded, A.clsExpanded { display:inline; color:black; } DIV.clsCollapsed, A.clsCollapsed { display:none; } SPAN.clsPropattr { font-weight:bold; } #pStyles, #pCode, #pSyntax, #pEvents, #pStyles {display:none; text-decoration:underline; cursor:hand; } /*** jhyde added ***/ CODE { color:maroon; font-family:'courier new' } DFN { font-weight:bold; font-style:italic; } /* End DesignDoc.css */ eigenbase-farrago-0.9.0/doc/privateBranch.html0000444000175000017500000002506311173714170021206 0ustar drazzibdrazzib Using a Private Branch

Using a Private Branch

This document explains how to use a Perforce private branch for Farrago development. A private branch allows you to check in code whenever you want without worrying about breaking someone else's build. Only when you integrate to a shared tree do your changes become visible to anyone else. This means you can save changes frequently (reducing the amount of code lost should your machine crash) and test experimental changes across multiple machines without having to copy files around.

Creating Your Branch

Before creating a private branch, you need to decide on the shared tree from which your private branch will sprout. The correct shared tree is wherever you have been checking out code already. The most common case would be //open/dev/..., which we'll use in the examples below.

Next, you need to decide where your branched files will live in the Perforce depot. Standard policy is to create your branch under //open/users/.... Never create your branch under a shared tree, otherwise everyone who maps that shared tree will accidentally map your private branch as well. So, if your Perforce user name is pmarlowe, you might use //open/users/pmarlowe/dev/... to branch from //open/dev/....

Your new branch also needs a name. A good name in this case would be dev_to_pmarlowe, which specifies the branch origin (dev), branched location (pmarlowe), and branching direction (later on it will become apparent why this naming convention is important).

To actually create the branch, issue a command like:


p4 branch dev_to_pmarlowe
Edit the Description field to give more details on the purpose of your branch, and define the branch view mapping:

View:
        //open/dev/thirdparty/... //open/users/pmarlowe/dev/thirdparty/...
        //open/dev/saffron/... //open/users/pmarlowe/dev/saffron/...
        //open/dev/fennel/... //open/users/pmarlowe/dev/fennel/...
        //open/dev/farrago/... //open/users/pmarlowe/dev/farrago/...
Defining the branch view is pretty much like defining a client view, except that the right hand side references the depot rather than the client. It's a good idea to include everything you think you're going to need, because changing the branch definition later can lead to trouble. For example, don't try to economize on disk space by leaving out thirdparty and trying to share the local copy from another branch; getting this right and keeping it working as things change is more trouble than it's worth.

Request Access Rights

Unfortunately, you won't be able to use the branch you just created unless you have access rights to the branched location, which you probably don't. Send mail to the Farrago administrator, providing the name of the branch, and wait for a reply.

Perform Initial Integration

Once you have the required access rights, the next step is to edit your client view to add your branched location. So, you might end up with something like:

View:
        //open/dev/thirdparty/... //pmarlowe.pi/dev/thirdparty/...
        //open/dev/saffron/... //pmarlowe.pi/dev/saffron/...
        //open/dev/fennel/... //pmarlowe.pi/dev/fennel/...
        //open/dev/farrago/... //pmarlowe.pi/dev/farrago/...
        //open/users/pmarlowe/dev/thirdparty/... //pmarlowe.pi/pmarlowe/thirdparty
        //open/users/pmarlowe/dev/saffron/... //pmarlowe.pi/pmarlowe/saffron
        //open/users/pmarlowe/dev/fennel/... //pmarlowe.pi/pmarlowe/fennel
        //open/users/pmarlowe/dev/farrago/... //pmarlowe.pi/pmarlowe/farrago
This would place your local pmarlowe directory as a sibling to your local dev directory. This structure is up to you to decide; something deeper becomes necessary when you have multiple private branches corresponding to multiple shared trees.

Now, before performing the initial integration (populating the private branch in the depot), sync all files which are to be branched so that you are branching from the latest version. In this example:


p4 sync //open/dev/...
will do the trick. Also, make sure you have no files open before starting the integration. This is very important, and is true for the other integrations described later on. Run p4 opened and make sure that the response is "File(s) not opened on this client." Mixing real changes with integrations will lead to much gnashing of teeth and tearing of hair.

Now, tell Perforce to do the integration:


p4 integrate -t -b dev_to_pmarlowe
The -t is redundant here but becomes important later, so get in the habit of including it whenever you invoke p4 integrate; otherwise you'll have nasty problems when file types change.

The p4 integrate command doesn't really do all of the work; it just tells Perforce what you're planning to do. To complete the branching in your client workspace:


p4 resolve -am
At this point, you should be able to build, run, and test under the local pmarlowe directory just created by p4 resolve. Once that looks good, check in (this won't affect anyone else):

p4 submit
The checkin comment should indicate
  • the branch creation
  • the trees involved
  • the change number you branched from
Your private branch is now open for business.

Propagating Other Developers' Changes from the Shared Tree

Without a private branch, the first thing you would probably do before starting a new task would be to execute p4 sync to start from the latest code. With a private branch in place, there are a few extra steps:
  1. p4 sync as usual. Make sure you sync both the shared tree and your private branch location, otherwise you'll experience unpleasant anomalies later. And make sure you have no files open.
  2. p4 integrate -t -b dev_to_pmarlowe
  3. Run the above integrate command again to make sure it says nothing needs to be done. Sometimes during a big integrate real warnings will be buried in all the success messages. If you get a warning, use the warning text and p4 help resolve to try to figure out what you need to do.
  4. p4 resolve -am. If you have made changes in your private branch, they may conflict with changes coming in from the shared tree. In that case, use the normal conflict resolution process.
  5. Run resolve again to make sure it says nothing needs to be done.
  6. At this point, you may want to build and run tests in your private branch to make sure you aren't polluting your private branch with someone else's breakage. Make sure you are working in the correct local tree (a good idea is to set up multiple shell launchers in your desktop, one for each branch, and arrange for the shell window title to display the branch location). If tests fail, use p4 revert to undo the integration. If you trust the shared tree, you can skip this step.
  7. p4 submit to update your private branch with the integration before starting on your own changes or integrating subsequent changes from the shared tree (it's not a good idea to mix). This submit does not affect anyone else, so you should always do it sooner rather than later. A good convention for the checkin comment is integrate dev_to_pmarlowe@XXX where XXX is the change number you synced and integrated from.

Propagating Your Changes Back to the Shared Tree

OK, now you've done some development, submitted changes to your private branch, and are ready to publish those changes to the shared tree for everyone else to see. Before doing anything else, it's a good idea to do another propagate in the forward direction and merge the latest changes into your private branch (just as it's a good idea to sync and resolve before submit when working without a private branch). After that, the steps for the real checkin are almost the same as above:
  1. p4 sync. And make sure you have no files open.
  2. p4 integrate -t -r -b dev_to_pmarlowe. The -r tells Perforce to go in the reverse direction. Since the branch name was chosen to describe the forward direction, reverse integration will be from pmarlowe to dev, which is what we want.
  3. Run the above integrate command again to make sure it says nothing needs to be done.
  4. p4 resolve -am and resolve any conflicts. If you followed the advice above about doing another forward integration, there shouldn't be any unless some other doofus just checked in during this window.
  5. Run resolve again to make sure it says nothing needs to be done.
  6. At this point, you definitely want to build and run tests in the shared tree to make sure your changes have been properly merged (even if you didn't get any merge conflicts). If tests fail, the best approach is to debug and then p4 revert to back out of the integration before fixing the problem (in your private branch).
  7. Once all is well, p4 submit; this is the only real checkin from the perspective of other developers, so your checkin comment should probably summarize all of the changes made in your private branch (and maybe list the relevant change numbers).

More to Explore

Did all of the notes above scare you a bit? Good. Branching should never be undertaken lightly, even in a source-control system with excellent support for it such as Perforce. If you carefully adhere to the above procedures, you should have very few problems. However, if things get sticky, it's a good idea to make sure you understand the underlying concepts well before seeking a resolution. A good resource is the branching chapter from the official Perforce User's Guide. The links at the end have some more info on general branching theory. Also, if an integration should go haywire, remember that nothing is made permanent until p4 submit. So if you want to back out and restart the whole procedure, just use p4 revert and then p4 opened to make sure that all files have been successfully reverted. eigenbase-farrago-0.9.0/doc/howto/0000755000175000017500000000000011173714170016664 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/doc/howto/reposStorage.html0000444000175000017500000003612611173714170022235 0ustar drazzibdrazzib HOWTO: Configure Farrago Repository Storage

HOWTO: Configure Farrago Repository Storage

The metadata in Farrago's system catalog is stored in an instance of an MDR repository. MDR supports a storage plugin system for extensibility; by default, Farrago uses a JDBC connection to an in-process HSQLDB engine.

This document describes how to configure other kinds of repository storage. You might well ask why Farrago relies on external storage for its metadata instead of providing the storage itself. Indeed, self-storage is the eventual goal, but at the moment Farrago still lacks some of the necessary SQL support. (Also, the bootstrapping challenge is non-trivial.) Even once self-storage is available, external storage is still a useful capability in cases such as those listed below.


Motivation

When might you want to configure custom repository storage?
  • One case would be when you want to reduce the number of stored databases requiring maintenance. For example, you might be using Farrago as a middleware server for heterogeneous SQL/MED queries or metadata federation. In such a configuration, a good idea is to tell Farrago to store its repository in one of your existing DBMS servers so that you have one less server to back up. Or your organization may require that all metadata be stored on a particular server.
  • Another scenario is shared access to the MDR repository from clients besides the Farrago server. This allows live catalog metadata to be browsed or queried from multiple MDR applications. Some caution is required since concurrency conflicts could interfere with the Farrago server.

Storage Properties

The Farrago build script configures repository storage by reading the file dev/farrago/catalog/ReposStorage.properties, which is in Java properties file format. If this file does not exist when the build starts, a default version is copied from dev/farrago/catalog/templates/HsqldbRepos.properties. The ReposStorage.properties file is also used at runtime to access the repository. Let's take a look at the default:

# /home/jvs/open/farrago/catalog/ReposStorage.properties
# Repository storage properties for hsqldb

# Class name of MDR storage plugin factory
org.netbeans.mdr.storagemodel.StorageFactoryClassName=\
org.netbeans.mdr.persistence.jdbcimpl.JdbcStorageFactory

# JDBC driver for hsqldb
MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.driverClassName=\
org.hsqldb.jdbcDriver

# URL for database storage
MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.url=\
jdbc:hsqldb:${FARRAGO_CATALOG_DIR}/FarragoCatalog

# user name
MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.userName=SA

# password
MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.password=

# schema name (used as a table prefix)
MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.schemaName=MDR
What do these properties mean?
  • The StorageFactoryClassName property tells MDR what storage plugin to use. Normally this will be JDBC, but MDR also supports a Java BTree implementation (see the BTreeRepos.properties file in the templates directory). The rest of the property names have a prefix which indicates that they are specific to this plugin.
  • The driverClassName property selects a JDBC driver (HSQLDB).
  • The url tells HSQLDB where to store the repository in the file system. The embedded ${FARRAGO_CATALOG_DIR} property reference is expanded by the Farrago build and runtime systems automatically.
  • The userName, password and schemaName properties provide additional control over HSQLDB access.

Build Configuration

Now, let's suppose you want to customize Farrago to store its catalog in a PostgreSQL server. Before starting, make sure that you can access your PostgreSQL server via JDBC, and record information such as the URL, username, and password. Here is an example using sqlline:

jvs@jackalope:~/open/test$ java -cp \
/home/jvs/open/thirdparty/sqlline.jar:\
/home/jvs/open/thirdparty/jline.jar:\
/home/jvs/postgresql-7.4.6/src/interfaces/jdbc/jars/postgresql.jar \
sqlline.SqlLine \
-u jdbc:postgresql://localhost/test \
-d org.postgresql.Driver \
-n postgres \
--isolation=TRANSACTION_SERIALIZABLE
Connecting to jdbc:postgresql:test
Connected to: PostgreSQL (version 7.4.6)
Driver: PostgreSQL Native Driver (version PostgreSQL 7.4.6 JDBC3 with SSL (build 215))
Autocommit status: true
Transaction isolation: TRANSACTION_SERIALIZABLE
sqlline version 1.0.0-jvs-1 by Marc Prud'hommeaux
0: jdbc:postgresql:test> select * from information_schema.schemata;
+---------------+---------------------+---------------+------------------------+
| catalog_name  |     schema_name     | schema_owner  | default_character_set_ |
+---------------+---------------------+---------------+------------------------+
| test          | pg_toast            | postgres      |                        |
| test          | pg_temp_1           | postgres      |                        |
| test          | pg_catalog          | postgres      |                        |
| test          | public              | postgres      |                        |
| test          | information_schema  | postgres      |                        |
+---------------+---------------------+---------------+------------------------+
5 rows selected (0.068 seconds)

The next step is to check the dev/farrago/catalog/templates directory for a suitable template. Not surprisingly, there's already one defined for PostgreSQL, and it just happens to match the connection information above. Copy it into the parent directory (dev/farrago/catalog) and rename it to ReposStorage.properties. If a file with that name already exists because you previously built Farrago with the default HSQLDB storage, you can overwrite it (it was copied verbatim from the templates directory by the build).

Now, edit ReposStorage.properties to match your configuration. At this point, it's a good idea to verify your settings. The Farrago build script provides an ant target named verifyReposSqlStorage for just this purpose. Let's try it now:


jvs@jackalope:~/open/farrago$ ant verifyReposSqlStorage
Buildfile: build.xml

verifyReposSqlStorage:

BUILD FAILED
/home/jvs/open/farrago/build.xml:1411: Class Not Found: JDBC driver org.postgresql.Driver could not be loaded

Total time: 3 seconds
Ooops! We forgot to tell the system the location of the jar containing the driver, and it's not one of the default thirdparty components. So how do we do this? The Farrago build system supports custom properties via an optional file dev/farrago/customBuild.properties. And the specific property we need to set is named farrago.custom.classpath. So, create that file now, with contents like:

# /home/jvs/open/farrago/customBuild.properties

# Tell Farrago where to find the PostgreSQL JDBC driver
farrago.custom.classpath=\
/home/jvs/postgresql-7.4.6/src/interfaces/jdbc/jars/postgresql.jar

# Tell Farrago to preserve our customizations
ReposStorage.configured=true
Now try again:

jvs@jackalope:~/open/farrago$ ant verifyReposSqlStorage
Buildfile: build.xml

checkReposStorage:

configureReposStorage:

verifyReposSqlStorage:
     [echo] Successfully connected to jdbc:postgresql://localhost/test

BUILD SUCCESSFUL
Total time: 3 seconds
Passing this test does not guarantee a good configuration, because it just connects without trying to execute any SQL statements. However, it can save time in eliminating basic connectivity problems.

Now, run the command ant createCatalog. This should rebuild the Farrago catalog, storing it in PostgreSQL as requested. If you get a build error, it probably means you have a deeper configuration problem; see the debugging section below for help. Otherwise, you're good to go. Runtime scripts such as farragoServer should work automatically, because ant createCatalog emits the customized classpath into dev/farrago/classpath.gen for use by these scripts.

Let's take a look at what happened behind the scenes. Returning to sqlline:


0: jdbc:postgresql://localhost/test> select * from information_schema.schemata;
+---------------+---------------------+---------------+------------------------+
| catalog_name  |     schema_name     | schema_owner  | default_character_set_ |
+---------------+---------------------+---------------+------------------------+
| test          | pg_toast            | postgres      |                        |
| test          | pg_temp_1           | postgres      |                        |
| test          | pg_catalog          | postgres      |                        |
| test          | public              | postgres      |                        |
| test          | information_schema  | postgres      |                        |
| test          | FarragoCatalog      | postgres      |                        |
+---------------+---------------------+---------------+------------------------+
6 rows selected (0.013 seconds)
Aha, there's our FarragoCatalog schema. What's inside?

0: jdbc:postgresql://localhost/test> select * from information_schema.tables where table_schema='FarragoCatalog';
+----------------+-----------------+-------------------+-------------+---------+
| table_catalog  |  table_schema   |    table_name     | table_type  | self_re |
+----------------+-----------------+-------------------+-------------+---------+
| test           | FarragoCatalog  | MOFID_SEQ         | BASE TABLE  |         |
| test           | FarragoCatalog  | PRIMARY_INDEX     | BASE TABLE  |         |
| test           | FarragoCatalog  | Contexts26        | BASE TABLE  |         |
| test           | FarragoCatalog  | ObjectsByClasses  | BASE TABLE  |         |
| test           | FarragoCatalog  | Properties        | BASE TABLE  |         |
| test           | FarragoCatalog  | aibn_1057         | BASE TABLE  |         |
| test           | FarragoCatalog  | aicp_1057         | BASE TABLE  |         |
| test           | FarragoCatalog  | ae_1057_1086_1    | BASE TABLE  |         |
| test           | FarragoCatalog  | ae_1057_1086_2    | BASE TABLE  |         |
| test           | FarragoCatalog  | ae_1057_1087_1    | BASE TABLE  |         |
| test           | FarragoCatalog  | ae_1057_1087_2    | BASE TABLE  |         |
...
Blech. If you were hoping to be able to query this schema directly for metadata, forget about it. The MDR model-to-table mapping is very low level as you'll find out if you try querying some of those tables. For SQL access to metadata, use Farrago.

Debugging Catalog Creation

When catalog creation fails, MDR usually suppresses the real error information and gives back a generic unhelpful message such as "Failed accessing storage factory." To dig out the real error message, add the following line to your ReposStorage.properties file:

MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.debugPrint=true
Then retry the failed catalog creation. Buried in the output should be some useful details, e.g.

...
     [java]       [mdr] org.postgresql.util.PSQLException: Backend start-up failed: org.postgresql.util.PSQLException: FATAL: user "digres" does not exist

     [java]       [mdr]         at org.postgresql.jdbc1.AbstractJdbc1Connection.openConnectionV3(AbstractJdbc1Connection.java:460)
     [java]       [mdr]         at org.postgresql.jdbc1.AbstractJdbc1Connection.openConnection(AbstractJdbc1Connection.java:214)
     [java]       [mdr]         at org.postgresql.Driver.connect(Driver.java:139)
     [java]       [mdr]         at java.sql.DriverManager.getConnection(DriverManager.java:512)
     [java]       [mdr]         at java.sql.DriverManager.getConnection(DriverManager.java:171)
     [java]       [mdr]         at org.netbeans.mdr.persistence.jdbcimpl.JdbcStorage.<init>(JdbcStorage.java:125)
     [java]       [mdr]         at org.netbeans.mdr.persistence.jdbcimpl.JdbcStorageFactory.createStorage(JdbcStorageFactory.java:108)
     [java]       [mdr]         at org.netbeans.mdr.storagemodel.MdrStorage.<init>(MdrStorage.java:288)
     [java]       [mdr]         at org.netbeans.mdr.NBMDRepositoryImpl.initCheck(NBMDRepositoryImpl.java:726)
     [java]       [mdr]         at org.netbeans.mdr.NBMDRepositoryImpl.beginTrans(NBMDRepositoryImpl.java:223)
     [java]       [mdr]         at org.netbeans.mdrant.MdrTask.execute(MdrTask.j
...
Once you have fixed the problem, delete the debug setting to avoid spurious printing on standard error at runtime.

Maintenance

As a developer convenience, the Farrago build system provides the ant targets backupCatalog and restoreCatalog to perform offline backup of the catalog and database. However, it only works on files stored in the dev/farrago/catalog directory, which is where the btree and HSQLDB files are stored. So if your repository is stored off in another database, these commands won't work. Instead, you need to use the backup/restore facilities of your DBMS.

If you try to re-run ant createCatalog again after a successful installation, you will probably get an error such as "Package extent named 'FarragoMetamodel' already exists". Normally, ant createCatalog avoids this by blowing away the repository storage in the catalog directory first, but since the repository is now stored elsewhere, this doesn't work. You have to do it manually:


0: jdbc:postgresql://localhost/test> drop schema "FarragoCatalog" cascade;
1 row affected (1.221 seconds)

Packaging

So far, this document has assumed the context of a Farrago developer build. How does all of this get packaged up and delivered to an end user? At the moment, there's no easy path. A manual process would be to perform a database export from the external server after a complete build and packaging the export file together with ReposStorage.properties. Then an installation program would import the repository database and tweak ReposStorage.properties with site-specifics.

What's missing is a way to recapitulate the build process as part of Farrago installation, so that nothing storage-specific needs to be prepackaged. This should be fairly trivial, since the ant tasks used by the build are just thin wrappers around MDR API calls. This should be taken into consideration when developing the currently non-existent Farrago installer.


eigenbase-farrago-0.9.0/doc/howto/index.html0000444000175000017500000000171611173714170020664 0ustar drazzibdrazzib Farrago HOWTO Guides

Farrago HOWTO Guides


For users: For developers:
End $Id: //open/dev/farrago/doc/howto/index.html#2 $

 

eigenbase-farrago-0.9.0/doc/howto/medmdr.html0000444000175000017500000007577411173714170021044 0ustar drazzibdrazzib HOWTO: Use Farrago SQL to Access Metadata Managed by MDR

HOWTO: Use Farrago SQL to Access Metadata Managed by MDR

If you are using MDR as a persistent repository, chances are good that at some point you'll want to expose your repository data as SQL views. This makes it possible to use an off-the-shelf query/reporting tool to browse your repository, generate reports, or just about anything else.

The Farrago DBMS platform makes all of this possible via its SQL/MED extensibility feature. This document describes how to make use of the MDR plugin.

Getting Started with Farrago

The first step is to get a Farrago build. See the developer jump-start page for details, or download prebuilt binaries. For very simple queries (e.g. filters, projections, and limited joins) you don't need the Fennel C++ components; pure Java can do the job. But if you want more comprehensive SQL support (e.g. ORDER BY), you'll need a build with Fennel.

After you have installed Farrago, make sure you're able to execute simple queries via iSQL-Viewer.

Farrago Talks MDR

For an example MDR repository, we will use a test btree repository which is generated by the Farrago build. (If you're using prebuilt binaries, this isn't part of the distribution, but you can get it from the Farrago-only source download and change the unitsql path below accordingly.) This repository contains just the MOF metametamodel. The first step is to tell Farrago where to find this repository. This is analogous to mounting a device in Unix in order to make it accessible via the filesystem. Execute the following command from iSQL-Viewer:

create server mof_repository
foreign data wrapper sys_mdr
options(
    "org.netbeans.mdr.persistence.Dir" 'unitsql/ddl/mdr',
    extent_name 'MOF',
    schema_name 'MODEL'
);
Explanation:
  • mof_repository is the name we will give the repository in Farrago. It will appear as a top-level catalog name.
  • sys_mdr is the name of the foreign data wrapper used to access MDR. Farrago allows you to define and plug in your own, but this isn't necessary here because the system already provides one for MDR.
  • "org.netbeans.mdr.persistence.Dir" tells MDR the directory in which to find the btree storage. This option name has to be quoted (with double-quotes as an identifier) in order for its case to be preserved correctly. Any properties understood by MDR can be passed in this way (allowing you to choose a storage representation other than btree, for example). The path is relative to the working directory; depending on where you ran iSQL-Viewer from, you may have to modify it accordingly. Using an absolute path is usually the best approach. Note that option values are always single-quoted (as string literals, not identifiers like option names).
  • extent_name tells MDR what extent name to look for in the repository
  • schema_name is bit of a hack. Normally, in a repository with a nested package structure, the root_package_name option would be specified instead, and all child packages of the root package would appear as schemas. However, the MOF repository has no nested packages at all, so in such cases the schema_name option should be specified to make the namespace conform to the standard catalog.schema.table convention. Choosing an upper-case name will allow you to avoid quoting it later.
Once the server definition above is created, you can directly query the repository extent if you know the available class names from the model. Let's get a list of all of the metaclasses defined by MOF:

select * from mof_repository.model."Class";
NOTE: object names from MDR (like "Class") are case sensitive and have to be quoted when they aren't upper-case to begin with. The reason mof_repository and model don't have to be quoted is that they were defined by Farrago DDL, not MDR. The results should look something like this:

Number of Records :: 28
name  annotation  container  isRoot  isLeaf  isAbstract  visibility  isSingleton  mofId  mofClassName 
Tag    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000036B  Class 
Constant    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000364  Class 
Constraint    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000035E  Class 
Parameter    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000352  Class 
Import    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000034D  Class 
Package    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000343  Class 
AssociationEnd    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000033E  Class 
Association    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000331  Class 
Exception    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000328  Class 
Operation    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000322  Class 
BehavioralFeature    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000031B  Class 
Reference    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000319  Class 
Attribute    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000030E  Class 
StructuralFeature    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:000000000000030A  Class 
Feature    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000306  Class 
AliasType    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000301  Class 
StructureField    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002FF  Class 
StructureType    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002FC  Class 
CollectionType    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002F9  Class 
EnumerationType    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002F6  Class 
PrimitiveType    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002F3  Class 
DataType    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002F1  Class 
Class    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  false  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002E2  Class 
Classifier    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002DB  Class 
TypedElement    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002D9  Class 
GeneralizableElement    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002D4  Class 
Namespace    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002BD  Class 
ModelElement    7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394  false  false  true  public_vis  false  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000002A1  Class 

Now we know the column names, so we can issue a more meaningful query, like finding the names of all abstract classes. Since the isAbstract column has type BOOLEAN, we can use it directly in the WHERE clause.


select "name" from mof_repository.model."Class" where "isAbstract";
Expected results:

Number of Records :: 9
name 
BehavioralFeature 
StructuralFeature 
Feature 
DataType 
Classifier 
TypedElement 
GeneralizableElement 
Namespace 
ModelElement 

Result Set Details

In the first result set above, notice the hexadecimal string ID's for the container and mofId columns. These are MOFID values, which are essentially object identifiers. The mofId attribute represents the ID for the object represented by the row in question (so in the above example, they are ID's for Class instances). The association between Namespace and ModelElement gives rise to the container column in the Class result set; it's really a foreign key referencing the mofId column of the Namespace result set. MDR takes care of the object-oriented aspects, so we can query for Package instances, which are a subset of all Namespace instances:

select "name","mofId" from mof_repository.model."Package";
Expected results:

Number of Records :: 3
name  mofId 
CorbaIdlTypes  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:00000000000003A3 
Model  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000394 
PrimitiveTypes  7D749D32-73FA-11D8-9D44-AFBC9CB2AA77:0000000000000272 

Notice that the mofId for the row with name=Model is the same as the container ID for all of the classes in the first result set. So this means all MOF classes are defined in the Model package. You can use a join to navigate the association; try the query below:


select 
    n."name" as container_name,
    e."name" as element_name
from
    mof_repository.model."Package" n
inner join
    mof_repository.model."ModelElement" e
on n."mofId" = e."container";

Some other result set details:

  • Besides the mofId column, there is an additional meta-column mofClassName associated with every table. When you query a leaf-level class in an object hierarchy, this value will always be the same (the name of the class you queried). However, when you query a non-leaf class (e.g. select "name","mofClassName" from mof_repository.model."Namespace"), the mofClassName column can be used to determine the actual leaf type of each object returned.
  • Datatypes of result columns are inferred automatically using repository metadata. All columns show up as nullable (even when the underlying attribute is mandatory).
  • MDR does not supply any precision information for string datatypes, so Farrago (arbitrarily) chooses VARCHAR(128) for the representation. This will probably change in the future; for now, a mechanism is available (described in the next section) for overriding the default with a different precision.

Local Metadata

So far, we have been querying the repository directly using our knowledge of its underlying package structure. Normally, you will instead want to capture at least a subset of the repository's metadata in Farrago's own catalog so that it is available in standard format (JDBC metadata calls, INFORMATION_SCHEMA, etc.) for use in third-party query tools such as iSQL-Viewer (or in your own application). You will probably also want to define your own data dictionary views on top of the raw repository tables to transform the metadata into a more useful format. There are a number of ways to go about this:
  1. Use the SQL/MED CREATE FOREIGN TABLE command to import metadata for individual tables into the Farrago catalog, specifying column names and types explicitly.
  2. Use the SQL/MED CREATE FOREIGN TABLE command to import metadata for individual tables into the Farrago catalog, allowing the system to infer the column names and types.
  3. Use the SQL/MED IMPORT FOREIGN SCHEMA command to import metadata for a collection of tables all at once. This is not yet implemented by Farrago, so it won't be discussed here.
  4. Use the CREATE VIEW command to define views directly against the repository.
  5. Use the CREATE VIEW command to define views against metadata imported via one of the first three methods.
Here's a CREATE FOREIGN TABLE example:

create schema mof_schema;

create foreign table mof_schema.exceptions(
    name varchar(20),
    annotation varchar(1),
    container char(54),
    "SCOPE" varchar(20),
    visibility varchar(20),
    exception_id char(54),
    unused_name varchar(20))
server mof_repository
options (class_name 'Exception');
Explanation:
  • We first create a new schema mof_schema under the default LOCALDB catalog. This schema will contain our imported metadata. This imported metadata will remain available even if the repository becomes unavailable.
  • In this case, the CREATE FOREIGN TABLE command overrides the default names and datatypes known to the repository. The names are defined as case insensitive, so no identifier quotes will be required when querying this table, except for the scope column whose name happens to be a SQL reserved word. And the datatypes are more reasonable than the defaults (e.g. we know that the MOFID's for this repository are fixed-length 54-character strings).
  • The table name exceptions is never seen by the repository at all. Instead, we explicitly tell the repository the desired class_name via the options clause at the end.
  • If the column names and types had been omitted, they would have been derived automatically from the repository metadata. This may be undesirable when you need control over case-sensitivity or datatypes.
Let's query the table via the local metadata:

select name,visibility
from mof_schema.exceptions;

Number of Records :: 2
NAME  VISIBILITY 
NameNotResolved  public_vis 
NameNotFound  public_vis 

If this is the only information desired, we can create a view to capture it:

create view mof_schema.exception_visibility as
select name,visibility
from mof_schema.exceptions;
The same view could instead be defined directly against the repository metadata:

create view mof_schema.exception_visibility as
select "name" as name,"visibility" as visibility
from mof_repository.model."Exception";
Note that in this second view definition, the column types would be based on the repository metadata rather than on the overriding types specified when the table definition was imported.

Try This At Home

If you made it through the above walkthrough, you're ready to give it a try with your own repository by following similar steps. There are a few things you should take into consideration first:
  • Repository Storage: If you're not using the default btree storage, you'll need to specify different options to the create server command. For example, if you are using JDBC storage, you might specify something like:
    
    options(
        "org.netbeans.mdr.storagemodel.StorageFactoryClassName" = 'org.netbeans.mdr.persistence.jdbcimpl.JdbcStorageFactory',
        "MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.driverClassName" = 'org.hsqldb.jdbcDriver',
        "MDRStorageProperty.org.netbeans.mdr.persistence.jdbcimpl.url" = 'jdbc:hsqldb:/home/hsqldb/stored_repos'
    )
    
  • Package Structure: If your repository model has no nested packages, you can use the schema_name option as in the MOF example. Otherwise, you'll need to specify the root_package_name option instead. All packages under this root package will appear as schemas under your repository catalog. If your package nesting structure has a depth greater than 2, you'll probably have to choose multiple roots and issue multiple create server statements accordingly.

  • Concurrent Access: MDR's default btree storage does not allow more than one process at a time to open the btree files. This means Farrago and your application have to take turns accessing the data, which is probably impractical. MDR's JDBC storage may provide a better solution, although it needs improvements in performance/concurrency control. So for now, usage of Farrago for MDR querying is probably limited to proof-of-concept.
Let us know how it goes for you.

TODO

Show how to use IMPORT FOREIGN SCHEMA once it is working, and also show metadata browsing via iSQL-Viewer once that is working. eigenbase-farrago-0.9.0/doc/FarragoArchEngine.gif0000555000175000017500000011741511173714170021532 0ustar drazzibdrazzibGIF89a        $(, ,0 4$ (<$$$8 8 ((( < 0 DH$0$,,,$4$@P000(8(U040,8,Y444Y]888a0@0],D,e<<<i a @@@qәt]ViHhf! rE$9W , :9w9iϱg@ٕqD(AbP>! B#zR(U,{p8h>Ac+4"/ ΐL m;'L [ΰ7a ;*&p,dv"#⩕z q$I ƭKHB,jKEV^E{谔L*[Xβd[L*26<ؚ0CrZVu.8Bm@F.m!ՈD_3s559hdr'MJ[drm*0Ӡ!|q79z3ps&P:H$0(8cBtf0<6" " 1f;沗ch[SseisZcrz%Q+,gMtf]{HCPJ&p YNWZ`tL@DBh r7IG`~~~'~aQl`~l 7{`{}W{`UP{{F緀Χm0~ /$`aP@'WM{!`7XWjEZ|7{W}N` zLaC8>$@*i1_8z\O^wag$glaO8a@6gp|(~+-h7l~7~~a~aP}{h$"X{7|֊' xh|7(Ww F<(a }{XWYyg@pl~g8axU(莥XS'Dxi` zѧBRvP(@`GxYN0˶}}uhCv'3iih~8T^tP׃M#JxD` IWavUxy58I$p v;HvOِB{R٘7a h9QYpMYeԚ*1im؅ĹY y Yvfo%)Iy+Q։ݹ9* y홞ɞ) iy 8ٟy韣&$zv^y݈{%ZAZ*zڡ:J 'j"$:,Z.3ڢL;Ơ `ʠ Z:@FzR*PR:TZVzXZ\ڥ^J?L:)]I_ڦnpr av:iy yIǦsuʧeyjp~:ڦ*mIzKZ֨ک}0:hJ}azpڪ]Z mzSʫÊzºV:Ъͪz&jܺي:ຮ*ʧjzZa=V02}0y20c ]P`=P  [+ Lگ4 eZI* }**Pq0T*m@%PQв%K";$۴VvQPvV}q<˲c`PQQV`Z ib{/U( q %Pvpv˳R[۵_;Qj-V`}o[L+veTKc`IU{{QP2 m`>p kf  m@<;Q {{I gҋe';ڼ=}0}-ks{ KsV۸[Gs;+<K-+K*k uiC+q{뼌{0kk˷S*{*uW:q۹KQܟ zn N]3 S.UޛWY.I]ntI._m~-L>59b~dS[lmkk^npeZl\;{[bQ1=.~̸Vܲ Q8 ̾e۹ ]=PVQjNlo[ c-ܲ<짎ދbk2}铡#{9-а;ҩK ˽ܸ l&-V2ʻbd^;7 ßk~N.-^juyV0}еo Q;l[,el , o l 7 0+>˹o;Ӕ|N¬-[4-3|gKƇ<@UZӞ>lŧmv)*[.\b)k6o,bƍ ňf{r[Ǽ$~酾탏\>]ϛɃ|a_I+e߻{ ìɨ 8;xQZ6vRNtP:z[lo1|+UTU^Ŋu1#("kLEVZmQRn(YƱe,X1O]Yiw܅y"*Vlq#ǎcm1WcˤW%\t6병 RlܻaN$J1 ѥCcRɘ-&!SL7'3J5+S3TQGNi S,@IK)'LI=6ئ.%*66YeTgV.S;#Vċ)I,UmUV-w}O~]]Jرu^N6_}霶C!ɋXo҉6J@*q+r@:)ڑFi駡iz묯V뤡0$d,lEdFeu;Z%9Jp .#L\q_#C&6c3<⦻ta;uՉW=v@<'mwt'uهϛ^'>y0uvpyާ_wேVx]>(zD 7>~Q~~e}eRO>J~C?y/)cgyEmj]58&Ѓ'Vw G B?"WA&`r?b8D"шGDbD& 1UrM,6[2#V j*:D#FA6iDҢtFVM% 7"v: Lz 3FKؐ&Lc;FJCcը-GB#Wv2 (@] ֈaC5I%(%͛%x[FRd0sɟJ \$c(ҙM2p$TW+p&$HGDNK06A"!I[%ħM 4)Ov>8tPh0Ha7RCeOt9w9/kSUל& V@Li63;ǒIܜ3WaHvl N0s|r 3ABy (wQF=hBT$FIX GЃX`0mICSІIrtPt[][HR>3 I;B\qklyYVז;r5bc om0"@IIZ6!B+il7ÁIDX0HħnS XOV,4Aҫ2Jh0tA ,qoGڴjd l]-HJ 8%)Z"&Zf³,?{RpEXK-Crn xbR@Mp(lWVd%ݞʛkm8\vn+o$+#f%=xebvJ;!#d c b_) AԛO bYX39UMqv&حe30s61֏ 7ޭ;Qj,Zσh$L 4X` ȥG+Ԗ{ ABrITA5R [.Vb3K?βi`V01vm\ʒ4#dF7קU;ԫ$F=nӤ¹5r]s׿50Y 7j䕸06cV3֗(-vqEAƭƷ޽A:,T[> X0d0ZcȼiT TL`^(vx roj1]/Jdz "+e~W1^_s,:<% t2;}J€ xI_B?ۿ˿@$ ,@< Z. >P?`ar=쫿J6ظz8**񻄈BJl. A(+ӎ<2:""߻-k -) ", !.[ ki8)A5 _`4'a61( ?H& BRf+MikJB(/B# 8JԌ![ s*Pʃ+(r^s8HASکeYɕfH@a]iGy'""#*^GP`9!+@gS y ID֘;CHr/3RH%r I0|I?˼3[ ǚ3E1r f cpG0H∾4B\ͫ$%+B˃Dk lSIHf/\%»|- ע4C04 %xLZqaA7cL3E ,Vr)@Dl?Խa70H|/Ƒg4DT괸$I/z+: u,3,Lt7M}$&`PxHC$CiL+cc pN *Qܺl[ػ@OG Gʧ2 !5MKML+(R7xIH/*PPs9/.U/*2 5֤QAxPBT5PNTQ UR-P5UNT]UV-UEUU5Y}U[VUQ%CH ĎehW9P~W|W>|W-؀X5XEX=Xm׉}XX>؃;@ 5PD#YP*(V**Ya}2@2a(BR J>#*]]&6b$P>X/ŀ0` Eܳk689:;<=>>@A&B6CFDVEf. I xdHIGLKLdLQeJ6eOdN @BV7\K6 ]2e}e_f>]$$6]Nbla(hV_b_e_.$e/1;H4F ѥW&8}~f.'3e]b~$Xbaib>pheb5 b-E `a>]h}Bb$%?h^|&1h~ݥVe]ef]fc~觎jk)o\U!lٚ>D!JM`+꽵L}MB =h|^>^i׭gƃ~h$pl6o^nb}$]icV iZ =z l ZZ/$Ȟl.gVg^jU,j}i݃/* XD&Ђe޶6&nޠ=f#FhFk.onfr]huFifMb$ H hvhvkM[eo'W3ڀImfVX7힕k6X_.9^&X:q:rՖB:l"A g'2J6wsUZ(0Nyq3vGWlofVT]x.ڥAvmgv6q\a>wtv~2i/[Pjsjb(>Gatu~'woރb۝,FgdEy_6?>,oYtWj^)b&Wq}V!~b.'A_$[ܐXafn}Ugb6괿WM[vzzeuFg|5zea$2^^L{{|q{[{h.hh/^Vln(_o^u˧}1ܪun %م]"^n w^qi6wɯʯ뗛w/}(zRX!,Ou!\w7n {>,h „ ʙ!Ĉ'Rh"Ɗ^#Ȑ"G,i$ʔ*Wl%̘2g&#Μ:wJ#РBFQФI=¨RRju!Or͹&ذbǒ-k,Z6m;ѧҸEƭӫz+\-l0Ċ{\+1OuE:yiS8r*`͢/fl4Ԫ ;AZk|wܹK.K.11uk%ۦm[(n,=w&.J$)a 42H5Sm:Pt x x 8 nHÃF8a^arH(!: 8#i~9duE $I}:9~6 e( N1%UZyehP%cPaz9%an9feb~io&T9a~%|w$ 0GVt4{ %0i^=Q("%[LNuPf@nj i7j QlgGV_jkWŪmbkD+ *}4%7d6kڑvXdGK>\`f:/)[ ?6ަ2~^Ix,pdUg^pYvl%0ۜھzb<$ctaof*ΝN+ŭl.[XqȰ2+ vD)"ElQ&iGft2`s}tRD5[V'eZW5Xy}tc4>Ŷqowy6Z* AjA^:_Uj)MrMxFSFW D9MI *G]V]ۇͥ1nzf|GS_w'ڃ}yDqijkM$v--."<@n2fDiC{Ҡ_ {|> (*R؃T~ 54>1(  E:2 R]hC{F" ˞d(iCՇfpAeLl[|LWe5'p>#HeI(Etɇ=}\iXEv⫺# w4Wv@Tٶrd18Wzt?'eWč6R$$)LHr"P, N$2G[ քϮK)|>4=lCiK@͓Ofaҳ+)1K(S)̔3c#2x(LJ]aS,&)#l?D@²vc/7ڳ.UY5'B7Gs'C1u%&U֡Q=R)V>>!I=(cK*VST8g?1ÓΤ 1+y١ ]s>Wro" Ѵsx}$=/3ϱRV'Zm-Hd=#KVL13K<-H[ hCZ6qjks$4Vg٢1e|x4!1#YbMl!Mz%w ۛ}ED1lwؽ7'gs6}avd gъ2y*0GNœcq~-q ;F6ҫfQ#UPRI[,2Kfkm(mAKcI&oijn+K^J=VH;$ԚӶaTY4W5"_ơbˮi43(N~$ !}\7k=:}jr+:N7n{ˮ UcKkvmԈ Ql]L/.<|xs◼8XqKƗG}o6I:FRHCӻ:[ĹÎ^$v3raOQcE(G5vc + B6w~6CD;@ܚ93_ j/=fxY2mz{; [>'cW_%S1f9e*! E?  ":`P T^ fn v  Ơ ֠ ܠ`5j՗ !,4>!FN!V! ^vN=$!8famaϝHV!٭."#>Nir!!V"D#a#n"#NR$JR%V"&*"'a#T'zbb (b)R@#-!/"L$-R+b,!n=NB\bPX#ҁ B]Bl  8 0^|2*,6c΢NHB55$ x@P@PhP>?\"@x7$ЁbPL$!c\a:];ccNc--J4A^!p#Rx $MA L֤ B2%07zc0A#x`P$H\Id=#!J&U"FZO DLP e>^B[:dl eEACN-֥_#!hVF\Wz%$N<-r xR4f %PfF%AE0BeffrQޢ5ACjff2dh^G*V2af%b2cJ56!4-6rbhk6dlfgr"'j"e1ltVBlfR&j G5M_A:=99YSs5!HGKP+VnYąKll0eL$j%PgC:(P@hhZ:gT^B%$ b%XP'ʈ'j@̑~ITHlQ荠Qh.}  $AKb 4DdDi JiNz4a!XbJc*$f0Ve>r#_sn0j $[iU*]uVTL` Pu*TlN|ˀyLȐ~LF*(xA`&%Q f\!`f@ x`}i2i\!%P@$ e%cRTt&ŴV+P\넆뷪:P@$` & N…[@~lQ .5y QeX@e}V X!%$hЯnܰ#:*2ا]o I RQd/\ Q QKnPrkh,6ɧ(pIM {Nn!h`#!/ 3FЌ HFZ7A*J $dX-cDc Ts׾qNVIͦ-4mP1d܁%L)FB G#$5p%%c2FR, Q T-dNaLQ1ozTq3{|?{>{ߚTЦ/R D 3'&B qT#8b/"HM^q1~$a㡮PV~DPgHjJuOQCs`HtZLtN8JFe4Lw^MqNߧw@U%JP7tYY 'E~k^TJ!p:Am6!$d+dE$!x>ntd!33EAC\GgB].\uW-X%t8 LKϚbϴeJ b>B7cCzPFK6R:dnvlLS*P5n6Zjcrk3",Als5YӶeKw_Vd0ʴ-6p%}&|o^bdPt_#] v_v&ww7}E`ry_7tm% ^|{}Ggi@#@f7bf:GhZSP^i389E`Db"y7c^B0j +7};jnxrLi\j$xlnfww8xE`@!A"x#BEԑZf#˷_=O LTo%9#f\sDB$Ta$\Pyvz[\CP|{˦j-dFo_O7"cd"gf*hꢇ7:|9EDzv#a"xPtzlNPRꣷ7k5˺PvkH{{>#A92:o%H{o 9zz[yDHa{`P `>P$A9#W"{F<[ODX|R$B ; $4A'ycN˗!ȍ|sѼDؼ\ A!H`A!Xd?"X7}>~D G#@A2b"%@ 0;'y;ZC= |A>闾G>뷾뗾LII߾>S SnC *K>R!A@ZKAvê~ ϗ!7do~h??@|8`A&T!F8!3faqF5r1$#3n42H%OrBp yC砜?w&B4P .%UiSME=4MUWJ=iWN,):lY{|]iDCjzd.]лD~naÇ'+aNǏ!G/HJFhP${!s#˰(l+%P-CO1S#CL(KL/O J7Q(3+ӊ>3Ȭ(=RB MP6,p,u :} a1p>06?*TD__E oj-`DH I`,Xm4ngD>H# Îjt9n&59[dۊS&(9ExlZiN)^5ժZ)Y4 sB u(=_K{i9a!hV$,d@N#6Z"@R>M/!DV)ރD /p¥+i)п0D:,Er` Nm[5]OPd- (@+ sox}н#U=iY4I|oK&x.a*ZS?Yi_SK!&v&&me޲ffe_cX_CZliXJe٤l)-K.A TJn{b%;ܫ$ow^dE-cO{]"ֵyudwcmmRխwug zWCo|k_z!/{x^n]fW?.xzQETU 5+2A &eep87~]c36Za="qdG9ٵJ4|\dk GͰm9c]HX"ɠn :Y4N j'w刭 ΔҐ8f"ZƇ!y//ыq =EiLd*m7Ҕ޴flpn֛> N[ӑ´g YQsDY)X  =;,oSt0\wFf{ |ָ2]Rؚmg#sf%!{fwuӠv1.-6ø *eƶ~ 2aD \ W"WkeCR|vaiq}@V!c0ӝq %ޞno%X{;^FwkԚFuLy6;uEQ9tjef)bNLZRHэd])!݊>br^q6e̦/h;ts17=ug.=^@Sc^͊3|)gɈk~:o3s鬶Σ@¿[j"3t2uoʋ-\&%qI6̴/-9"#ljxM| au#>O5 0D/7$Pg Fhp Y^(1vOFcR1{ `b] d% ۤrԄ//$|2OiVbUhNŬíbQL!'N%p P mfp':qhڨ\go1\QF{2& Y UcnȎz\L[i20| Z$l~<k&$_%M F ϔB'B0]Ұ(bێE)@2PereRRR+ 2Z1dPc`ON-M,s.g 2 ֒DR|#R-xMb ɘx%1vu%a&1 ?.F  - C/5Kk25} ňGN,R+ )\2}D pBM&'"'p72' Ed}>'C+~.T:׆ʪ55*6q'''b'S b=.,3>GK;J**6:SBn4 5A3F?LoBD@fB T:Hs4 DWB]BUt>A$^+D$6*AμkGQGC;[XtH#^;bTb +)NJ0S)L(`C'+a)F(8-99)&k*҂]3ƲaVLw):|+,YKW95/:1#aYa%-fR]@:l)b:i!is-u+I{)ڜ5ͨ=LLJ ç\DDn~bo^cݝݙӤg1v38N= 滋\zt>#6tl$zkqn<4b41ǻB'ӳ=]x790A % dD'`ՆQ$# ֈwLDۭKE"II s½`|.ڝ?Cd e<0, y#W񽻁}qڬ_2eF{:-mI2 .JX"0IA m(1N8K0m,lȰ/b!eM>,أHkΝ<{ 4С>1D4ҥL62D#t\zJ'. 4X=6ڵl4:6ܹtڽT-=VFQ]<Ŧb%اI'K%s4}؂2pavB)1Oc2bOx;r=4m!) 9R`̓ ı:OHy&b8 ?ݥONM*dUIH$ER>ɚE`^`XyW]6{LHa^ 7ligeQ'fq&CmXB!xbQk&QpVA5R4V}Y ݈!ԃmڤ~ fbI}]"URO &R] $u e hJhg&hY(g5׃ٵ^in*nɘcMauIɤsTQ"5ce QתLVR2cϵZDԜM 2D UzEZS &pm~ . ^|& 4B ^8%պk@RH-:B pp\Kx8ؤ ەŧ&᫇I&"f\zjG*Bu&^v2s$u&v~H7{&m2NQkV @D1qq]ga}HIq$ ^H|IU~Jv @raIjX7ݙi*Q}hem׾Y" dmvwϹhA)'.Yek:O{ {-|I<7K.&YQF+6@Q_@rE2Ͻ@GwjKTBiLQD/6ۈo l /{`WΏ'?4!ֱMJVF6d%)HW*ȕ4D,\ҍ c,CK)w #ҕ`R%3B'2ܥ5^љn {؄5>B!5Ku]&e1l)eM$6 P-܄R¦w!*tXㅵR$t Bhm`A϶3o IOm~jvҦYQSG} f{Jϱm XUnkmcsV|>e]`VeO^`h_.*<s.+4lQ&<>v,h]jlIB2W5lZ.R5!UL#{ / Ӵa5iOewB%PBt [fw=/"#xx: 2  mdpo#)Q # /` /, 1 Ϛ`EQ#HBa楠a ؃v[xAIrB+QanS`̱F@x!( 1Fbo(BR@х/Z -ո7N<1K K`Abv!+#6OqMBxf[$)E(ހBa#VT37FiK !c+%^6gC)v.\j T{HAj:ڵu5‚=J{ۯ|aoD`78RB pn8p.athm/)&G?|$/O\a!L7|w_ 2I&9]|=]8sEL:u NaIa ~t'^obj%g]c%Fb@FXVlw5Rg[|k}.~` yҒ_㐟]p}HAz汀B>s Rx޼\:md5KC =w#S34_= ^Xb8Q3I|&"%$q,4I,cz"4{5#pur{"m7ARq""I+b8+"*qR,A%9=}C*z QGrJ*:V9 (ww}:b?+xAzB##2A3%B2$8cz4:UbgB,@"aÅ$=9Ԇso#'Uaq|Y5~|H4Hm@6a,4g!;$:=-a2+avWrE` q}O4Dz8΁xxx@W*A+h%C4r *03#8Ȏ i@)X43k276RF3:c";6i*cѨ5;R=ѓ!8Ї$09ɨ%u)j YT$&4=+ A2#S*H8+9R2$&d~H@3;і#AW:^Yҕ(!CFcY4b|D皯qxщI#lY ǕݷLo0k)ple(V<jP3Pjj0utv3i0CɛbDewᙾ)onBj{c@;93x/Njx?qtԖ3,71]EW_%}Z6w009YvFy byMRrD{r ^F%j)^0(E ":RC RvBx}Ң<0wa l6j pWDC8W:<ڣcFʉ0Wu(P3 E@Eg 0^Z|w09I;D48:ؚ8+jRZ:C:1A2lf  E@vCdJ%8]#B/=(Q+SV<` `5@(x Z|Pr(tIM⩠IF/:lŪ=ʨT;ꭊRj@(eJ-1Cip Hs3*ZӖS#h4a"6H:K7z"G}{ʦݚJA v3uXTK(( $(Ih9;᯦+(#+`kxJU `q aZSı' 3#؄Hٸ*DٍH;L0)vs&sFU r$arp+ HI2ۗxH7 { P;ཾCQCǮ)5G#Q1R"*JZs[[E+I KN۴]0 (UwvcP;gEP&|  #&1c22|I! 1/l.8yDSGww ™3 J*O<47'`y *}zL3`-^hPW q@( kijHۛtĊ ПeH:O;tJ+7fA+H23ȅ(6)<ت3 c )`"Xo ʗtsod@AxWAM\+v˹0k << #`ys³l ̖ά0 k ݜB; RD,78 -M]@  - ZО!yМ l zBsZ>1-3M5m79;=2M`CMEmGIKH Q-SMUmQYv ¼ Co߼ur"tČu+<%ֱ\#0Wuhx=lMsn]|rvt^lqq 8.Ŕ02ٛ6L>vua y}Amؗ=u)(1)} 1NS>q!vh3@g]c!bPnA[KzM{-ڬy|F5GӽUH R0Q5bFȕ5USO%'^ .-$%LJkk}vs1OWܳVmg̯MSY '1QM&jzr &)52']SYQ''-uܽ j wܵ]QWq"SaQZ%)N}SV\WauR/ŴSi^SfaXؔ<yɝI^YNLg&^aSoM);EBW#LdEڍdpI)ڙg ͊b׼)yw"蛮^/-a!W<~2U3ݬ~ w [Nn3pLJWǎvQ^qAr"Qe>^6`aU̞=5~{S5^VZCPSBJVAn·")qt!ɾ5&q"h,NXsYY} u5ksN5Oe2,OLaF׈ bntwb~뽞 n}pGUWwKOsݬaS{> q'-<^($h# װah0\l?u$]媏(cQ 6hұ/$؇6%M(^JQƲw`wQI}W=ƿώ/_ OQ!NDž5ƅ} B]I !.dCGDXE5n#G>d>$YARN^41eΤYaK d /t\9KB\:db(! }$hS^m:)'ĉ_Ŏ%;Sʠivؖ/Υ[!δT^rH(5 RKP^ (*5je5-asZb\4Iez oBt*cL6k-&^"ƕģK˥+OMjS@_:Қ'Mu{^U;|oQ\}ݴ!*+!) < LhJ,l":k =ѽFIJk5;LF1򂼟b\@B%8DȌ,`/d /KQ, #QJ2eR13Js! Z7"2-yc2yHb%~sAf<(CbO1tRΤ9/1hIQ,Q#IH#U,Lg N:#wUVasXY21}Xie:Ԙ[2`4 1\tUw]vu]xww'^|7Q I2 ⭍LJ(bava#xb+vvK,)d1eHFn'h<>kϬ.=Єb$!RBDA!,*nƃ> RR ^!Bx?WGl$N"xѰn3Lb$8p)(9(*!$HS2H=q\UhcE.qaqR+3Eh lbT*M$P|[wo\'x ~p'\ gxp#FLUcx=q\#'yM~r\+gy]r\39Bk64Ns]C'zэ~t'=;ȩsnҭ~ug][֣ I*QHYzv]sןlk$A*TBIf; x'^[G^rIw;x2!=yЇ^!o|Eh%| 1GkPȧʚ!Fe_'>K'@y 5™>ؔ!Q zO߷'oC$GRQ>ɫ'зQhV& z@,K@@{"- "@+ (+qH} Ax 4@9*!y/ $;F{CE\DF89d̓}bHF0ؘ0::ظh9ИPD9@(L\G\-K LLţ{D!x ]D0@E0?A@9YLU$VfČX\ơc[D6EnB@F@`68FDmF?Hǎ6xGkw3p[z8mǍCHjLh h6\ș{*8kE*ō*X8M]d0X@И%@dƙd|FaTG{3HkI^%vDȍ3%%h^Ȣkw{iʊ{F?o\ɍ !EF!P%D^\Jeƍku|ID؃8:xF6ŶlITm38KD(pGTF2-3LFǀ80*Ʒ3(MŘI_H 9p,OIA.5p)+o?B*Gf>-<(,KJ^IH!:Cd!SY@OUFHG(Z2;/T@@BAC<.f}4o eL)e])8 "5`CP%CαIHh&KX2ƮH&U6HHN60=.#bî]5$0~H6^z-&N7PdHޞ~:"lN&7(fFhagg^"Bƥǭh3i^Kh7t.##c 5n& iRI(Ji[YiޖKr&?NҀXjfGPAe2#X\:n?]ٞ:ƀ7b|&+5Xe .57&ɞk`"le7(`x%8ViR{g±p2EX^:`p^݅7sC`q/ڶ 4.h ^&އp.)޺qE3 @_tyoAtqprEqqo,/!1O230_ݎn*76w35_ss7ؾbs70t",`.xsfs93^Э`!9GϲI4' :g _ O[Q3i,ر HuF_ 6 X*)CYN~10nx hz׍DwN w? ,{ =nXxtvxv0P B B*b0q 9@,KjK.\WxJ(=;vƈ>#*:xoHNW[) <*xg~&!pzdJ1!) 2K(t2wt{Pi"`؝D,XC| ) )+aX M V\;#} ; ŗw bؿ|ⵐy0vfωI ؑo" rB*⨥=Kc=5`~3ꗉXsi>"Lp!Å4(q"Ŋ/b̨q#DŽtXHoބ1%˖._Œ̚6 BNj  *t(ы+}&*R#M#*ujԦTJDUX +#ԘxP&%e+תܺDͫd钴0-Qw1ctC72 R<, HrRO85넓[kɋ8r:-{Q><xlW|Dʤlبȕ˿5rNRB3FJ |=$23VS$^F#Y x||%%,ibXr 3`R$ x1HTd bZ zCDDUH2$QDwoP! @^!cg4hblgRs޴xPJ ZF'ݢBiTHa=RD$rک,QaR4⦤ 1"l Ȯ~۬>BFI\rgSA-ovpNG \sZ2#F/31ȼHZrKPЩBq!#\A!xPJ\DFu X%=Rȏ)P|x;7<0seo DM"E,]slK!2eWbk'tt#PRDط=']]aJI:ݸ㈮x.cn9ރ ;808B/-czKՄփj:.Svm}M{8ª)|RMO_U:0~<S7VET=Hà/N@6!XFf#(_P@OnOy n؀D()! '¢Jbh#;\\%5WX00r!SQ\ _HM\J^#h`EUPtRبș&SvGSA#G:"iv\!H-Ra|$%cɄM%Mb'CiJ_<%+J+YR\-si&fZa(ì\zg+-q?$%w#XSh3iN\I 4Ix 82j3'*88t*9 *id2-aD|{1T=A Ms3H]1.aC^ҖDh4"Ȁ?rd˩Kdb.s]*0W@DTԘ)&CS")/v0x k2*0݆QL RMLi] 2BU3GAY$0"S.,r z '*d* [&Iב@oZS AQ~aDx,ɷqJZxX??Sƨ7JJwn#mUj=Ƈl!W|mSt[@;>TTZ=B@TC($J M  DR=@AQ%YEAdB !aqJENba? ?h]Tl n J}M r؜M)l,aAׅI}M^PaT@fa$ ;] Z,N(\ ڨat_5֫VFRkA+]YäTC:ܟ-"hKT\$*mq!J [T0 e^(Dp5 lNTdY@"%/c??d@ @dAA"dB*B2dC6'%gd[A؜ UôQ]HZaT L7HΗ`fY$c:}NS3 X^<QtdY|fl.I(5Ob`9f:|iM(B+m%nJ|BߜmN'ERGϐ`*GfE-gC)ޡS *֦tF*S4jE-\hD;uɕGRjj]5JЇ@P4@HkZkj H~PNV4Ȼ!m*ķNtokMXiqpք,Mԫp$n ʄ:KpLo4lIJb,KܩfPwl,j6Ŧ\$ŒlHhʊzE(>H˺lH)mp>6P/%͎lކL2F<5;+ R†Hrkq`Cz%f> dmmmέan"zAҪPA'|G* xwQD>$H@$a.@n5@90hkG 8/w.9C%^D;hA%o sD25.ܰC0C"6;D> $ 0E`Ca2>C1aB0sA2=lC/h`y7C ;P5CE2?C33%B/ctHׯ4* 0}D|/D7-8Eph3x7:UlKd :qOx 2S"|8:@{z.xy{34vwJ8w?~4P)w+4A9vH xpCKK9F?\CȰ w9D@  ?yt ^;*@ 9?@*@삞 G;Bz#T':*l0^C'8+ 9F6M-Ae@§/D::zB4u(w4\^`+g:H}zC.|w(oLIB r~{XCįu(+Y5D;+0Czc{_E1Bz؉8kO{(k{Ʋ{Ļ{ ,uzJHQP| *ɴGF07zKȺc3X·KV Gm#/ȓ4|'0缥}зI-#}(gr#CKP}cIk}s=xחp8:Γ|Ca"$hOz3S I)X̻$Iej৳ٗMF^r>V1^>拳[\=C6OiɏeY˔HLA d) m;꣤@qJ F"◩0`KZ TMY7l>@h$)|rb,X GVI fD"4xa„\)tbD)VxcF9vdH#I4yeD/@Ƹ0F %ծ9ue.--TP.uZ0fc 0eXcɖ5{mZkٶ=KYuՇPmƐ:)t <8a:eP2Ŭu2ݏ`vthѣIv f::/^~0Ѥ >V4NysC˙7wztQ{2l_ANȘP `a݂ M*դM:$U#+5ʊ: !7 w   0.J9M<U\eI]~YnmWfi瞻 w袁ݥ覝v"I"p|E%el0㚓ۘQX毟Dʸvv\gz:)_|\Ya _as!&*Ϝ=ǘ"y/6*0t:iOD (GNpď*/\^& c_qdn2njIzÒy+(+a?B TC}"k"`% y8܈`"DD i^XV/728t ` ~5"$2d8I|90aF3¯^ C 1TG2rCg#*==2w k;y6>z#R,gAP‚$bJGm0Di2(j,i97ѓVÂ2s(Aw?2D8rX%GdYKk^0o"ওbjw[I k) 'v0{4qs#kMӖӈ/I83{CHSm;ܒWA" h('Zϡq `' Hfh9 `D'ن9tC`fIifuiAYUARg)TceSIU~U"VYJtiU+J-AnMZZװZ˪jWC+` kM*lU,$.Jl,Y~pe9K l->ЎU+-NZljki 9p oEmy ,n!r%iZ- at%׏9Hjvf4U+wɋ~0" #8nhr9V }] Nf_JaDK`[-*z/ZTxĩ9|qXs0Fua!o& F<?x=W>a x,ֱ1(U=B;V2x'xH,LpkY8r' Hu|LH<x/ѰG) ;!S.|y@]1ܨ^#thBAH'_ &p9IĒvP4iPOHtBgNگ)Zo BN6kc( ;eigenbase-farrago-0.9.0/doc/extensibility.html0000444000175000017500000007721111173714170021314 0ustar drazzibdrazzib Farrago Extensibility

Farrago Extensibility


One of the innovative aspects of the Farrago architecture is its approach to extensibility. Of course, features such as user-defined types and routines are hardly novel, and earlier DBMS projects have taken extensibility quite far already by applying it to features such as indexing and access methods. In this document, we'll explain how Farrago radically redefines what it means for a DBMS platform to be extensible. By way of illustration, here's a plain, boring DBMS which hasn't been extended in any way:


The Gist

Farrago provides system-level extensibility instead of just feature-level extensibility.

What does this mean? A platform with feature-level extensibility defines a fixed set of extensible features, and for each one defines service-provider interfaces and mechanisms for plugging in custom implementations. Here's our friend again after his feet and one of his eyes have been customized independently:

Examples of extensible features in existing DBMS projects include

  • routines (stored procedures, user-defined functions, user-defined aggregators)
  • datatypes (OODB's, user-defined types, datablades, cartridges)
  • table storage (e.g. MySQL storage engines)
  • indexes, access methods and associated optimizer parameters (e.g. GiST)
But what if the platform doesn't have the feature you want in the first place? For example, important capabilities like sequences, materialized views, triggers, XML, or federated queries may not be available in your favorite DBMS yet. Or perhaps you have invented something new and equally powerful, and are trying to figure out how to bolt it on.

Without system-level extensibility, your options are limited:

  1. If your platform of choice is open-source, fork it and patch in your new feature. Every time the platform is upgraded, you'll have to merge the changes and deal with conflicts if you want to keep up with it. If your innovation is good, you may be able to get it accepted as a contribution so that other developers will share the maintenance burden, but impediments such as project politics or license conflicts may prevent you.
  2. Attempt to shoehorn your feature in by abusing one or more of the existing extension interfaces. This may work for simple features, but the result is unlikely to be very attractive to users.
  3. Drop the notion of reusing a generic DBMS platform altogether and start building your own from scratch. Don't laugh; it's been done too many times already.
Farrago aims to change all of that, and its architecture has been planned out with this goal in mind, leading to exciting new possibilities for every part of the system to be involved in extensibility, and for entirely new features to be incorporated:

How do we do it? There are a few keys to the approach:

  • The architecture is model-driven wherever possible, and the model is extensible. As a result, extensions automatically propagate throughout many parts of the system. More on this later.
  • All important system components (including the catalog, session manager, parser, validator, optimizer, code generator, executor, and storage manager) have corresponding extension interfaces and communicate with each other primarily via these interfaces.
  • Extension interfaces are defined coherently rather than in isolation. For example, you can choose to plug in a new catalog model extension in isolation, and you can choose to plug in a new session personality extension in isolation. But you can also design your new session personality to manipulate your catalog model extensions. Likewise with optimizer rules, table storage, and access methods.
  • Object-oriented and pattern-driven design principles guide the placement of component boundaries. For example, an optimizer rule is defined independently of the kind of optimizer (heuristic, cost-based, randomized) which utilizes it. Usage of Java and C++ as the implementation languages means the extensibility mechanisms have natural representations (instead of cumbersome constructs such as tables of function pointers in C).

Use Cases

Here are just a few examples of the variety of system-level extensions the Farrago framework should be able to support:
  • SQL/XML
  • analytical features such as materialized views, efficient star schemas, and SQL/OLAP
  • "personalities" for making a server emulate a particular DBMS product or a particular standard conformance level
  • federated data management

Reality Check

The pitch above may sound like a lot of pie in the sky. And in truth, there are limitations on any extensible architecture. Some of them are due to blind spots; it's impossible to foresee every possible direction in which the system might be stretched. Others are due to practical constraints; we may know that a component needs to be involved in extensibility, but we haven't yet gotten the time to do it right, or we haven't come up with enough use-cases to feel confident that the extensibility design will be generic enough. Still others are simply out of scope; for example, you may be able to cobble together a distributed system out of multiple nodes running Farrago, and the loosely-coupled design may assist you in this, but the architecture does not address distributed-system issues, so the promise of extensibility isn't going to be very relevant.

So, even using Farrago as a platform, you may at times still be faced with some of the unpleasant choices enumerated earlier in this document. However, you may be able to contribute extensibility enhancements to the platform and use them to satisfy your requirement, without the need for any ongoing patch/merge maintenance. And because of the system-level extensibility design goal, others are more likely to assist you with such an enhancement (assuming you take a sufficiently generic approach instead of just slipping in a special-case hack).

The success of the Eclipse project, an IDE "for anything and nothing in particular," provides hope that it's possible to do something similar for data management services.

In case it's not clear, taking advantage of system-level extensibility requires skilled developers with an understanding of UML modeling and server-side Java. For end-users and less-sophisticated developers, feature-level extensibility is more appropriate.


Plugins

Extended functionality is added to Farrago by installing plugins, which are packaged as jars (with accompanying shared libraries for plugins which contain C++ components). Plugins are typically installed via DDL commands, and in most cases installation does not require restart of the JVM running Farrago (exceptions are noted below). This list provides an overview of the currently supported plugin categories:
  • Catalog model: these plugins contain extensions to the standard catalog model, expressed as UML static structure models. The standard catalog model contains definitions for the usual SQL objects such as schemas, tables, and views. A model plugin can define novel objects; the example provided later on in this document explains how to add the definition for a stateful random-number generator (similar to a sequence). Once installed, these extended objects behave exactly like standard objects; they can be contained by schemas, referenced from queries, involved in dependencies, etc. Besides UML, catalog model plugins also implement extension interfaces for controlling object behavior, e.g. DDL validation rules. Catalog model plugins are installed via the ALTER SYSTEM ADD CATALOG JAR statement, which requires a JVM restart. The system supports multiple active catalog model extensions.
  • Session manager: these plugins define shared system state (e.g. repository implementation) and the state associated with each session. They are not installed via a DDL command; instead, a top-level container for Farrago selects one of these to initialize the system. (Theoretically, it's possible for multiple containers in the same JVM to load different session managers simultaneously, but in practice that is likely to lead to trouble unless those session managers are designed to work together.)
  • Session personality: these plugins define session behavior, including parsing, validation, optimization, and execution. Session manager plugins supply a default personality plugin for new sessions, but a new personality can be selected at any time with the ALTER SESSION IMPLEMENTATION statement (session personality is typically stateless for this reason). There is currently limited support for layering multiple session personalities within a single session, and each session can have its own personality.
  • Foreign data wrappers: these plugins define standard SQL/MED access to data whose definition and storage are managed externally. Foreign data wrappers are installed via the CREATE FOREIGN DATA WRAPPER statement.
  • Local data wrappers: these plugins are similar to foreign data wrappers, but extend additional interfaces which allow Farrago to manage the definition and storage of new table types locally. Local data wrappers are installed via the CREATE LOCAL DATA WRAPPER statement.
  • User-defined routines and types: these plugins are standard SQL stored procedures, user-defined functions, and user-defined types installed via the CREATE PROCEDURE/FUNCTION/TYPE statements.
  • Catalog repository storage: these plugins control how the catalog repository is stored; typically just one of these is installed as part of framework installation.

Toy Example: Random Number Generator

The rest of this document walks through a specific example in detail to give a deeper sense of how system-level extensibility works. The source code for this example is available under dev/farrago/examples/rng, and can be compiled and built to test the extensibility mechanisms involved. (If you have a Farrago developer build, run ant createPlugin from that directory.) It also serves as a good clonable starting-point for creating your own extension.

The premise is that we'd like to be able to add a random-number generator object to the system. It should be a first-class object like a traditional sequence generator, and should have persistent state to guarantee that the pseudo-random sequence won't repeat for as long as possible. Here's some sample SQL for how we want to be able to define and use a random-number generator:


-- define a new random number generator;
-- persist its state in a file named rng1.dat,
-- and give it an explicit seed so that the sequence is deterministic
create rng rng1 external 'rng1.dat' seed 999;

-- use a generated random number as a primary key for a new department;
-- generate the integer without any bound on the bits used to minimize
-- chance of a key collision
insert into depts(deptno,name)
values (next_random_int(unbounded from rng1), 'Lost and Found');

-- for each employee, generate a random number from 0 to 6 representing
-- the employee's day off
select name, next_random_int(ceiling 7 from rng1) as day_off
from emps;
To accomplish this, we'll need a plugin which can serve as a catalog model extension (to add the definition of a random-number generator) and a session personality (to add the DDL support for creating/dropping rng's, and to add the query support for referencing them).

NOTE: this example plugin is not designed for production use; it does not have proper concurrency control and transaction semantics, and its file-system persistence mechanism is neither high performance nor fault tolerant. Instead, the implementation is intended to be kept simple for instructional purposes.


Example Continued: Extending the Catalog Model

For this first step, it's necessary to use a UML modeling tool to create a definition of the model extension and export it as XMI. What's more, we need a way to reference the standard catalog model so that we can specify how the extension model relates to it. Here's how it looks in Poseidon:

Our new UML class (RandomNumberGenerator) is a subclass of the generic CWM class ModelElement. Having ModelElement as a superclass means that a RandomNumberGenerator has a name, can be contained by a schema, and can have dependency relationships with other objects. We've defined two additional attributes for it: serializedFile is the file-system location where the persistent state is stored, and initialSeed is the (optional) seed defined when the RNG is created (if missing, the current time will be used).

For such a simple model extension, usage of UML may appear to be overkill, and one could argue that a lighter-weight modeling infrastructure such as XSD or POJO reflection would be more appropriate. However, most real system-level extensions are expected to involve many classes with complex hierarchies and associations--a domain in which UML is the best fit. In addition, the rest of the system is JMI-based, and we want model extensions to work exactly like the rest of the model.

Once the extension model has been defined in UML, it can be translated into JMI packages and corresponding XMI deployment descriptor. To do this, the build script invokes the plugin.buildModel target inherited from the framework script dev/farrago/plugin/buildPlugin.xml. The JMI interfaces are generated under dev/farrago/examples/rng/catalog/java. The XMI deployment descriptor is generated as dev/farrago/examples/rng/catalog/xmi/RngPluginModelExport.xmi.


Example Continued: Defining Extended Model Behavior

Next, we need to add custom DDL handling. This is the job of class net.sf.farrago.rng.FarragoRngDdlHandler. It supplies a number of handler routines:
  • validateDefinition: during CREATE, expands the location of the persistence file to an absolute path.
  • executeCreation: initializes a new random-number generator (using class java.util.Random and the initial seed, if specified) and persists its state
  • executeDrop: deletes the persistence file
To tell Farrago what to do with our model plugin when it is loaded, we need to implement extension interface net.sf.farrago.session.FarragoSessionModelExtensionFactory. This is done by class net.sf.farrago.rng.FarragoRngPluginFactory, which takes care of returning DDL handlers when requested (and also other model aspects such as localization, which is not covered here).

At this point, we have everything we need to build and install a model plugin jar, and the installation would create new system tables capable of storing metadata about RNG's. However, doing so wouldn't be very useful yet, because even though we've told the system what an RNG is and how to react when someone wants to create one or drop one, we haven't yet extended the DDL parser to actually support the custom CREATE/DROP statements. (Theoretically, parser-generation could be model-driven as well, but most system-level extensions require custom syntax.) For that, we need a session personality plugin.


Example Continued: Extending The DDL Parser

Like everything else in the framework, the Farrago parsers are defined to be extended. JavaCC doesn't support this out of the box, but we have devised our own extensibility mechanisms on top of it. In particular, we use textual concatenation of the .jj grammar source files, and we design those grammar files to be reusable. Currently, only one extension parser can be active in a session at a time (unlike with models, we don't yet have a mechanism for combining multiple extension parsers.)

Here's a snippet of the RNG example DDL parser (dev/farrago/examples/rng/src/net/sf/farrago/rng/RngParser.jj):


CwmModelElement ExtensionModelSchemaObjDefinition() :
{
    RngRandomNumberGenerator rng;
    SqlIdentifier qualifiedName;
    String externalLocation;
    long seed;
}
{
    <RNG>
        {
            rng = getRngModelPackage().getRngschema()
                .getRngRandomNumberGenerator().createRngRandomNumberGenerator();
        }
    qualifiedName = CompoundIdentifier3()
        {
            farragoParser.getDdlValidator().setSchemaObjectName(
                rng, qualifiedName);
        }
    <EXTERNAL> externalLocation = QuotedString()
        {
            rng.setSerializedFile(externalLocation);
        }
    [ <SEED> seed = UnsignedValue() { rng.setInitialSeed(new Long(seed)); } ]
    {
        return rng;
    }
}

CwmModelElement ExtensionModelDrop() :
{
    SqlIdentifier qualifiedName;
    RngRandomNumberGenerator rng;
}
{
    <RNG> qualifiedName = CompoundIdentifier3()
        {
            rng = (RngRandomNumberGenerator)
            farragoParser.getStmtValidator().findSchemaObject(
                qualifiedName,
                getRngModelPackage().getRngschema().
                getRngRandomNumberGenerator());
        }
    CascadeOption()
        {
            return rng;
        }
}

TOKEN :
{
  < NEXT_RANDOM_INT: "NEXT_RANDOM_INT" >
| < RNG: "RNG" >
| < SEED: "SEED" >
}
The ExtensionModelSchemaObjDefinition and ExtensionModelDrop grammar productions are defined as no-ops in the standard parser; here we override them to accept our custom RNG syntax and specify how to store the object definition in the catalog (for later processing by FarragoRngDdlHandler). In addition, JavaCC allows us to define new tokens as needed.

All that's left is to make sure that FarragoRngPluginFactory implements extension interface net.sf.farrago.session.FarragoSessionPersonalityFactory and supplies Farrago with our customized parser instead of the default.


Example Continued: Testing the Plugin

At this point, we have everything we need to be able to instantiate RNG's, but we still can't access them from queries. For the impatient reader, let's use a quick-and-dirty approach: we'll create a user-defined function to do the job. (Later, we'll explain how to extend the query parser so that we don't need to rely on this UDF.)

Class class net.sf.farrago.rng.FarragoRngUDR contains static method rng_next_int which can be used for this purpose. It takes the name of the RNG and the desired ceiling and produces an integer. It works by performing a catalog lookup to get the location of the serialization file for the RNG, and then accesses that file to instantiate the RNG, generate the next number, and then persist the modified state.

The ant createPlugin task takes care of building the plugin (dev/farrago/examples/rng/plugin/FarragoRng.jar). Installing a model plugin performs some heavy-duty surgery on the repository, and should only be performed from a single-user instance of Farrago, so we'll use sqllineEngine for this purpose:


0: jdbc:farrago:> set schema 'sys_boot.sys_boot';
No rows affected (4.869 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> create jar rngplugin
. . . . . . . . > library 'file:${FARRAGO_HOME}/examples/rng/plugin/FarragoRng.jar'
. . . . . . . . > options(0);
No rows affected (0.197 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> alter system add catalog jar rngplugin;
No rows affected (7.887 seconds)
0: jdbc:farrago:> Closing: net.sf.farrago.jdbc.engine.FarragoJdbcEngineConnection

(After the ALTER SYSTEM ADD CATALOG JAR statement completes, the system is in an unusable state and must be shut down immediately; the next restart will complete the installation process as part of catalog boot.)

Now, let's give our newly installed plugin a whirl:


0: jdbc:farrago:> create schema rngtest;
No rows affected (0.21 seconds)
0: jdbc:farrago:> set schema 'rngtest';
No rows affected (2.223 seconds)
0: jdbc:farrago:> set path 'rngtest';
No rows affected (0.022 seconds)
0: jdbc:farrago:> alter session implementation set jar sys_boot.sys_boot.rngplugin;
No rows affected (0.049 seconds)
0: jdbc:farrago:> create rng rng1 external '${FARRAGO_HOME}/testgen/rng1.dat' seed 999;
No rows affected (0.446 seconds)
0: jdbc:farrago:> create function rng_next_int(
. . . . . . . . >     rng_name varchar(512),
. . . . . . . . >     n int)
. . . . . . . . > returns int
. . . . . . . . > language java
. . . . . . . . > reads sql data
. . . . . . . . > external name
. . . . . . . . > 'sys_boot.sys_boot.rngplugin:net.sf.farrago.rng.FarragoRngUDR.rng_next_int';
No rows affected (0.444 seconds)
0: jdbc:farrago:> select name,rng_next_int('rng1',7) as day_off
. . . . . . . . > from sales.emps;
+--------+----------+
|  NAME  | DAY_OFF  |
+--------+----------+
| Fred   | 1        |
| Eric   | 6        |
| Wilma  | 5        |
| John   | 1        |
+--------+----------+
4 rows selected (0.081 seconds)
Note that we had to explicitly activate the session personality via ALTER SESSION IMPLEMENTATION SET JAR. Normally, either a system-level extension would include a session manager implementation which does this automatically, or the correct default personality would be associated with each user profile (this association is not yet implemented).

Example Continued: Extending the Query Parser

The UDF above did the job, but it has a few drawbacks:
  • the syntax is cumbersome: the RNG name had to be quoted as a string literal, and if we wanted an unbounded number to be generated, we would have to pass a special value (-1 in this case) to indicate it
  • the dependency between the query and the RNG is not recorded; this means that if the UDF is used in a view definition, and the RNG is later dropped, the system won't know that it is supposed to CASCADE the drop to the view
  • performance suffers because the UDF has to look up the RNG in the catalog every time it is invoked (four times in the example query above because it returns four rows)
We can do better, but it involves digging into the Farrago query processing system. So if you've already had enough low-level internals for your taste, you can stop reading now. Otherwise, let's take a look at the parser change for our custom query syntax:

SqlNode ExtendedBuiltinFunctionCall() :
{
    SqlIdentifier id;
    long longCeiling;
    int ceiling = -1;
    RngRandomNumberGenerator rng;
}
{
    <NEXT_RANDOM_INT>
         <LPAREN>
         (
             <CEILING> longCeiling = UnsignedValue()
             {
                 ceiling = (int) longCeiling;
             }
             | <UNBOUNDED>
         )
         <FROM>
         id = CompoundIdentifier3()
         <RPAREN>
        {
            rng = (RngRandomNumberGenerator)
            farragoParser.getStmtValidator().findSchemaObject(
                id,
                getRngModelPackage().getRngschema().
                getRngRandomNumberGenerator());
            return
            FarragoRngOperatorTable.rngInstance().nextRandomInt.createCall(
                new SqlNode [] {
                    SqlLiteral.createExactNumeric(
                        Integer.toString(ceiling),
                        getPos()),
                    SqlLiteral.createCharString(
                        FarragoCatalogUtil.getQualifiedName(rng).toString(),
                        getPos()),
                    SqlLiteral.createCharString(
                        FarragoProperties.instance().expandProperties(
                            rng.getSerializedFile()),
                        getPos())
                }, 
                getPos());
        }
}
ExtendedBuiltinFunctionCall is another parser extension point. Our custom production and accompanying Java code constructs a SqlNode instance representing the NEXT_RANDOM_INT call.

But what is that reference to FarragoRngOperatorTable? Our plugin defines an extension to the standard table of SQL operators provided by Farrago. For each custom expression such as NEXT_RANDOM_INT, we define a corresponding operator (FarragoRngNextRandomIntOperator in this case) with custom behavior for validating instances of the expression (and other details, such as how to unparse expression instances back into SQL text). The validation code also calls back into Farrago to record the dependency of the query on the RNG.

Besides validation, we also need to tell Farrago how to generate executable code to implement the expression as part of a query plan. This logic is encapsulated in FarragoRngImplementorTable, which generates Java code for a call to an optimized version of the UDF defined previously. This optimized version (rng_next_int_internal) takes the persistence file location as a parameter so that it can skip the catalog lookup (which instead is done only once during query validation).

Finally, FarragoRngPluginFactory takes care of making sure that our custom validation and code generation behavior gets supplied to Farrago by implementing the correct session personality interfaces. Putting it all together:


0: jdbc:farrago:> set schema 'rngtest';
No rows affected (0.018 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> create view emp_days_off as
. . . . . . . . > select name,next_random_int(ceiling 7 from rng1) as day_off
. . . . . . . . > from sales.emps;
No rows affected (1.28 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> select * from emp_days_off;
+--------+----------+
|  NAME  | DAY_OFF  |
+--------+----------+
| Fred   | 0        |
| Eric   | 6        |
| Wilma  | 3        |
| John   | 2        |
+--------+----------+
4 rows selected (3.976 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> drop rng rng1 restrict;
Error: Dropping random number generator "RNGTEST"."RNG1" requires CASCADE because other objects still reference it (state=,code=0)
0: jdbc:farrago:>
0: jdbc:farrago:> drop view emp_days_off;
No rows affected (0.277 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> drop rng rng1 restrict;
No rows affected (0.052 seconds)
Note that the first drop attempt failed due to the dependency of EMP_DAYS_OFF on RNG1. The custom drop logic in FarragoRngDdlHandler does not do anything special to enforce the RESTRICT option; instead, the uncustomized DDL validator knows how to enforce that automatically because dependencies are a generic part of the catalog model, and our model extension is now part of the catalog model. Likewise, the statement DROP SCHEMA RNGTEST CASCADE will know that it is supposed to drop the contained object RNG1, automatically invoking its custom RNG drop logic as well.

Example Completed: Extending Metadata Views

Earlier, this document claimed that model-driven architecture meant that extension models propagate through the system automatically. We've already seen one example with DROP RESTRICT. Now let's see what it means in the context of metadata views. When the model was extended during plugin installation, internal system views were auto-created for each UML class in the extension model (contained by corresponding internal schemas for each UML package in the extension model). To expose these, all that's necessary is to create a virtual SQL/MED catalog:

0: jdbc:farrago:> create server sys_rng
. . . . . . . . > foreign data wrapper sys_mdr
. . . . . . . . > options(root_package_name 'RNGModel');
No rows affected (0.114 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> select * from sys_rng."RNGSchema"."RandomNumberGenerator";
+-------+-------------+---------------------+-----------------------------------+--------------+---------------------+------------------------+
| name  | visibility  |      namespace      |          serializedFile           | initialSeed  |        mofId        |      mofClassName      |
+-------+-------------+---------------------+-----------------------------------+--------------+---------------------+------------------------+
| RNG1  | vk_public   | j:0000000000001DE1  | ${FARRAGO_HOME}/testgen/rng1.dat  | 999          | j:0000000000001DE6  | RandomNumberGenerator  |
+-------+-------------+---------------------+-----------------------------------+--------------+---------------------+------------------------+
1 row selected (0.802 seconds)
To get a view with information more meaningful to an end-user, we can join to one of the internal views used to define standard JDBC metadata:

0: jdbc:farrago:> create view rng_list as
. . . . . . . . >     select
. . . . . . . . >         s.object_catalog as rng_catalog,
. . . . . . . . >         s.object_schema as rng_schema,
. . . . . . . . >         r."name" as rng_name,
. . . . . . . . >         r."serializedFile" as serialized_file,
. . . . . . . . >         r."initialSeed" as initial_seed
. . . . . . . . >     from
. . . . . . . . >         sys_boot.jdbc_metadata.schemas_view_internal s
. . . . . . . . >     inner join
. . . . . . . . >         sys_rng."RNGSchema"."RandomNumberGenerator" r
. . . . . . . . >     on
. . . . . . . . >         s."mofId" = r."namespace"
. . . . . . . . > ;
No rows affected (0.504 seconds)
0: jdbc:farrago:>
0: jdbc:farrago:> select * from rng_list;
+--------------+-------------+-----------+-----------------------------------+---------------+
| RNG_CATALOG  | RNG_SCHEMA  | RNG_NAME  |          SERIALIZED_FILE          | INITIAL_SEED  |
+--------------+-------------+-----------+-----------------------------------+---------------+
| LOCALDB      | RNGTEST     | RNG1      | ${FARRAGO_HOME}/testgen/rng1.dat  | 999           |
+--------------+-------------+-----------+-----------------------------------+---------------+
1 row selected (3.363 seconds)
A real system-level extension can include a script for adding such cleaned views to the catalog as part of plugin installation (not yet implemented: SQL/J jar deployment descriptors).

Conclusion

If you've made it this far, you should now have a good notion of what's possible with Farrago's system-level extensibility; perhaps you even have an idea for developing your own extension. If so, we'd love to hear from you at the farrago-developers mailing list.
End $Id: //open/dev/farrago/doc/extensibility.html#5 $

 

eigenbase-farrago-0.9.0/doc/faqProject.html0000444000175000017500000001343611173714170020515 0ustar drazzibdrazzib Farrago Project FAQ

Farrago Project FAQ


We already have MySQL, PostgreSQL, Derby, etc. Why does the world need another open-source DBMS?

Farrago is not an end-user product like these databases, which are focused on specific domains such as transaction processing, where they can already meet the needs of many users. Instead, Farrago provides a generic framework which can be specialized for a variety of DBMS domains such as federated query processing, data warehousing, multimedia, or replication. While it is possible to adapt a project like PostgreSQL for novel uses, significant customization requires permanently forking the codebase, because the architecture wasn't designed for extensibility beyond the type system. By contrast, Farrago has been designed for system-level extensibility via plugins, so the specialization process involves adding new components and behavior instead of replacing existing components with incompatible versions. The Farrago project model is very similar to Eclipse in this respect.

Why would I be interested in Farrago?

If you are a developer interested in creating a product with DBMS capabilities of some kind, using Farrago as a starting point can save you a lot of time. The Farrago architecture spans all of the layers required for a full DBMS, including: API's such as JDBC; SQL query parsing, validation, and optimization; query execution; storage and transaction managment; distributed data; and metadata management. And the implementation is fully component-based, with careful attention paid to dependencies, so that if you only want to reuse a self-contained subset such as storage management or SQL parsing, it's possible to do this without dragging in unrelated layers.

If you are an end user, you're more likely to be interested in a prepackaged distribution customized for a specific use such as data warehousing or metadata federation.


I would like to use Farrago to develop commercial software, but the GPL is a dead end for me. Do you offer dual licensing?

Farrago is being developed under the stewardship of The Eigenbase Project, a California non-profit. We strongly support open-source principles, and we believe that the GPL is the best vehicle for creating and protecting strong communities of software developers and users. So we encourage you to distribute your software under the GPL as well. However, if your organization prohibits development of or integration with GPL software, Eigenbase offers commercial licensing in exchange for significant contributions of code or other resources; contact us for more information.

Why does Farrago require Java?

Farrago's hybrid Java/C++ architecture opens up a number of opportunities not available to traditional DBMS implementations (or much more difficult):
  • Tight integration with Java-based application servers. For example, rather than reinventing cluster management, a clustered service based on Farrago could be managed through generic J2EE facilities such as JMX. There are similar opportunities for features such as distributed transactions, resource pooling, software update distribution, hot upgrades, etc.
  • Better extensibility environment. Writing a UDF in Java (with garbage collection) means the UDF can run in-process without having to worry about memory corruption and leaks affecting the server.
  • Seamless implementation for SQL standard Java stored procedures and object-oriented user-defined types.
  • JIT compilation of SQL expression and procedure code. Farrago is already able to implement many SQL scalar expressions and some relational expressions by generating Java code on the fly. (The same technique will be used for stored procedures.) This can be automatically compiled further into native code by JIT. This is a big win for commonly re-executed transactional statements as well as long-running complex queries.
  • Less security risk. Java is not perfect in this respect, but it reduces the chance of common exploits such as buffer overruns in non-performance-critical code. And the C++ portions use modern memory management techniques (string, vector, shared_ptr, etc), with STLport bounds-checking turned on for all debug builds.

Isn't Java slow? Doesn't that mean Farrago can't possibly compete with systems implemented entirely in C/C++?

Careful attention has been paid to keep Java out of the most important data processing paths. Where Java is used (metadata management, parsing, validation, and optimization, plus a limited role in executing generated code), its performance is acceptable.

What version of the SQL standard does Farrago implement?

We are developing towards SQL:2003.

What's with the name?

See the dictionary. But that's not the whole story.

Why a jackalope for the mascot?

The wily jackalope combines the speed of a jackrabbit with the fluid grace and complex headgear of an antelope, which seems appropriate for a hybrid Java/C++ system. In addition, the jackalope symbolizes a vision of elegance beyond our mundane reality (and is also reputed to be surprisingly savage when cornered).
eigenbase-farrago-0.9.0/doc/jira_button_120wx60h.gif0000444000175000017500000000406411173714170022014 0ustar drazzibdrazzibGIF89ax<BBB8#†.`BI- ,{5o&HA!],X@gD%hTh9)_vAMwr n$?h훷j--8%9ߔ޾n;_aJ1 D2FԐ/I (aQ0lKK рclRJx80 h* & @ a4bĐ@XHȍPڲ PPoQI_"ҁH`#6bD՜Mq1ctBe \7j7&8Y%T XZcvZZ%l%z^%0+W @ 40^.vjljq*@L0 !&nj:/|!kQ`ň8li–.N$\0l!c"6 $W ܒ* ޖs%@"!57l?wL|=4f{tIkdi:R #GBհjtmn4%&x c3 )@6jsͶԬǞPwPkTG$x)ćr).0݈\$Zx+.ʙG,h8Ų2:[i 8N 3Iͻ;9L) $?6;D#LoR^W>(  T`~43_ֺI󚦬 8H j%r&W)l|@u/4ݱg |uó("Ge` '?1 }.H[ ' <`&a #-J{SDAhpKC(j< } &z/xDgQll$\)9S@#G0@_!ZjpDT $)AhjF-HIN 90lqhs\ Ĵ#%GJzR;$)=V6ѓD%8D8셬Hc&X4f|$1yFcv#s3W7FF~mӴ0ŀ1+andgnpFқ,yN+dD6IZ@|tgʁZϟO,( !8g:=eyT bT;D6Ј|%%yϜ'u h4ҀL6gvåT0-CZ}kХ*PEႵpjPxi>՞J*b)EhTVT'huAddRZ: k_8Uu}AJp_uFDZUlqpݤ Zhh`$DȈ7x] ;eigenbase-farrago-0.9.0/doc/MetaModelFlow.gif0000444000175000017500000005237611173714170020725 0ustar drazzibdrazzibGIF89aE     00 ((  ( (00  ((0 0  ((00((00< < 88@ @LL00@@$$$YY00H H]]44@@0 0HH,$,P P(((@@0$08 8PP@@Y Y0(0,,,mmPP@ @a a8(8ii000qqaayyPPi i@(@L Lqq}}yy444@,@yy@0@}}888@4@<8<} }<<< @<@H8H@@@HŘ r&J!,*$rK(QJ#?QJhf: 5?*: J1T<G,eA:C_x׵|YALn&2ȸ0)&X:ӕG,>"=(Ha ڬ$ˤ*/%e7y+6c-!39%d|(wUv%TO'mp(,`L=,SNӢhEKk}"LHd, 5$)3"3G3.XB ;Nt Cy:7iV앯S S]+TQr ߊlgIٰ: A`S`[qVn6O ֩uHS _X!Hg"Vq5LocUͶW7JDdt.MYNBkC%34dNk+fEI|4G]bS1֌lv-V4R@t٧mZ-5u? /D5Wx[bCrbirD&&(Cu,ق dP~a+^[΃ 2rNץC^>5[ϖhA]LB;!˹",!23[I_.‡6783|֨3b!eBj"洬ajJV^EИ15!VGJ8ֳNv$'f+D jXRp{J}/n {ν[~0O.7OxM+f%87l p\%%IOr&/o |bo\&?9σ> ,!Kt3].MWtKꝶ:^;S]fOI>pT$px;ge_‹';-'h {g%0OaiOK>[O{ؼ>}w>O>`o|ُfRFfI " c˄W 1e~sJ%J*|0彩_\:ΔD*"s<VU,]=OWPu|w]N~,a\~%V5559.uQ:7 "4S$5@%eeXU1aEZ;K;" +E[!)qEb,h زj5 Ƶ"S0#3G`l- %x\4\@ a '%' hwa$P'G`a`8g2jHs%^*-)sEYr/u4[*6`2i2xŎ#S 6hHlҔ3ޘ" #iւ]Uc'Dg3$4F"Zi |*ӔW%2|VO,CCyq6_a'XC_⃋قiPq7sBaJesr h+ CD$"rJs@3zD@$â . -쓣u=N:%=^D&;*.բ:>>QT*S2eaK5n:pN6w%j'KD|ڨL'ꨒj: y::.J JڪZyzBgzګ}*ȚÚz* SЭj% ꭇj yx 蚮50{E@jp z;ky ˯+&J+ ˰7$[{(*벨ײ2&y6{8<۳A+?EKI+uwP N2VuMn9Ay^+{bI\upf{mjk!vpmom;/T}qxo|z۷]nr{fZ apCkhd+k kiuii[hP+K[{䦻KAۻwDepqW;v{f2@<$>Ҧnu;# 0Ea*.V˽zTԦ8ƚ.c-[+5! -^KJd!ELɿ![g#d4ee,^(FeKe#&(,6*?"jN*Q}ĆQ~5sX8ʗˬ QH_!H<6T:,nlD[,A*E.6s<#MJ@8Zԑ 8K[q1m>$o#H0$ 5T=;m*،d+W=Y'"cA)M[NPy/+]%ӈE%eܹhĊ ;jn4'ƉX3U #ȮܛRYJE*t.^0 cFuauH)L҂N+0e.unԪ䦌d M6$b\-AXBU&N~=F#Xlh")D,v )AddFL깨 T1ؘ81+O%*.V?cՆ1_ q8؂ncH j)-"ZEʔ[q^i i]4gFK=u-VLL~bi.Ydߋf r.66%6E9$HL.!6`Łc4W`28!"&viqcBŌ0t4'C&Acچs8۲ 5's \-d+ҍ *FR! "P"X3ٜ 2]uRk A\l5A QY Av#FC\ qq%KD"T)hTPEETRM>UjOY(]ŚUV&Bs` _͞EjJ\uV}* _6F+SyTYdʕSɚnrZxuqZjC1k̹lii%v8))4^ ɔ= ㅧoTV/gO*^]:4@\)trAmFf էU.-5@ ?#+%R L 6\S-dp6J_Ѯ +Dό3t8L$.#J8tY\M|.:8p([fĞ$D&Y\14aG[ū\|N;/(:l˜{(ڐ<ΧL(AIPM+/'q2i<O7,N9鄵V[LNK벴 )?B3(HE ;َ*u !$*ˢBiKك[EZEVqwP͛]t/сoF5`JAZ%=T ?d~5]=\/Q0ړW~y]7m!JLB<(.H2$ y{2WMDsb1b,&:ig dɺ3vgƫr҅6L\IY#y㜅f{刕hؐnX&4QHHCQtaJUK"2L9ɞ:ރsv{h[3?'=5UO9eP$1 OdzݖPPWr7ӝz U$HZPK*~S9jHi<~+<|Rh^&‡, I#,I=2'%AD`@ A `%et`5 >paA\P'Da BP/a Anƅ2!èІ<"^z4!"LhD&J&a&:ŇsaxM\T++*1cD#f? HcQʸ8<Ő_GPюAb GBF1* B񌅄$m@` p##xEs#aGMrҔE TԱhBA ^_K^NI6QnqD&`z`fe  1A&ӚRd3 U<5ř[h/v A pӝR9" |ˆ|g> yffH7U)Ԡ6`6(R~f$5 a( ihJr D y?t+E@Jur6X %™ԧN Vܹ էI]N ᩰI2qBVYU-~/`ATh]*)<ff1pU!XfK#,0 Ȅ7HYtfQX\?HYYhME`jDm]dӢ@Z(Nqmk\aF-""73aY*6h7 \@75$4B i^aʛEfPmia(X7$)@ʋP%pk 7wlezia  kK\ޅd@qUb/qU\@7qu\v@,LbeEd&7OrXLWreq"X gs.#rKuoev3q a\YA9 Z^zYi&4 -CZ qN??z2Dİft*#? Ca ~iLj-z/T+[ T )n"oBna{`󃊞ۈ6 uE -i4B;(fwWK8@uثwN#n!Lln.$"R2 , 85? +*P!ans;.9; Yw; 1ps<@p|= ex>~t8KG9vT{vΎ&ӭCw$"g鱆| [?d11 PSxk(ok>xWw{BNяנ,@ζ^4ǽ*">z /A~3h~k JC}g0W~w<1HO>t}п Q;1dٛ[? j5E@#T Fʄ( Cl 0Є\6Ϙ(Q P?N? 9L" a AЏS2 E#3T|!7P9`)EXS|ɋQ H$F쁅P)Lg|:(D) Od刉ꛔ󩃜Ǩ{)NJzr|[Gk,TFGA ^[0ۉ b` [0?  Md^ldp ^[Id^,dȔ Hٔ1 d  4W<ʡ< tiD iK FyᕃL+>ԐoDaTK5{Bl1˭ KO˭F6;LJЅ odL#̧ a [; ?AC%C BDFHuTJ]IJeMT$N] NURU 2S!WXYZ[]^_U\a%[5ec§deeV3ughV)jEkV mmnpq%k4sMtUW@dv=wW)yz|m}-X#؂E؞S؅ua؋]I{ZM PѢxѳ8َiOżL bi=S]WFX) jԓ [>m m_0P 8P ] %A%i Y]DI:$A %ٮA@۞xAۗ05㘽% MZڡ` (سϠ受-<Ĉ-JIX@%Yz]\.P`M݋]f ٖO8PG9I?diێMHl^hl~llɞʶldbKmѶ` `fvmK̆p׶mKpqYU m,..A^K=fGT nFn.n;kYEULN aKݲHdOho> =YbZoFգ-V RəPap0 ]oo? D<̜`O`\|qp5W?U@Wݐ[.dIېl$Eq' <`h!Wȸr>^ڱɥ(w 'L+hOxasN+a0he 27s@s<7/J)9aϑYVsDp<^@zRtE+˶X )Mj_huq&]޼ŠW˔)y0OLG afh}lTv:~ ro'EvKwHv(o.ejx'pwy|wyw~w~xy֓ =<>x<^3ϋǃ~x s>ueٯwx aP8Tx <.ixx6M q0٘ Ҝ|h}~oڏ }[On7WT7)ܷzg~*б'*p9~%~o_в?H-$ OǞd,h „ 2l!Ĉ'Rh"ƌ7rѠ,F,i$KWl%̘2gҬieȓ:w'РB-jcΝJI<)ԨRR=tҦUr+بW,ڴjײE8Imҭk̷p/݋HĊ3Zx/ƒ'SS}-ssp#.mbdInZXYîmSKiLY7/n8R̙"oyD`#→~R *O 䠄ZHjGr!y"%.4)(,-؉r&."Nr =H$ᣏX#F{ݑ0IJMbdSjI`Vaץ$)&i)ߚA&Sc)i }AP@Vށ8'I79b҉%9D0*ȞԘKAq: %A,ʞ0:B#ɇ-fI)_"&|Vhd8bI'-rWZ/-g@C"1jK,ydP"*--%Ӝ" ua{t&pJH:ӹ&hoX/:l/$2rlP4pMbG'?|rB8Bȡ\T#C8 H*0-, R%+3Q”‡u ULDSqA"6#8Wdb 0 H_IVgOU -&+UVT,0TZP}% .@hONW,+*0!z& d; ;/'%#;u_.`I'{ALJ4hB׃Ahr"Wg&Cp]A!TA +ZW^C bi( &aassͥqBY -@ @ՙn VºD@B P";` H.j׻6/MD3P 1b)K բ :EjVWk1N#F<ₒ]dէ )5.7*V4.v%_XKȄ{D1 Pȃ0# $`2٤:I?}JS2>+[W'L-c['%/K3ziL S=\&tgB9,5k'47o''9}c3Y'wNیpo'>}'@*HeA<ȅ2}(D#*щReT zY4Q\v? HJL)jFRԠ0efISӛG& Ky 65sڟ":D]QT⇩R&Up)H Mp!S,t:A!Azդ [^J h"Pj.uV`ƚ‚UsfVգl5 $`V6&lcX$E z8e= Bù\p@j˅S᯺l жB"I)6rUruEY 즀 &e B]H|V] @Wюu5i R".$~Q:h&la6쿂o :{/RcnpyOSu۵/2 \"W m6ptRSUArF}fQؕ)@BwvmbQN E$7<¢-2+i!WqAtcux^R_y,YXFg' 9t-k^ Bӝe2޺OzҘ!WHvgJ-b}h]5v` lDڸł -&6ñl.u mSYjZ>q! b+Aq6O%H| 2Ux9t}Y? DJSN:,,9n\ uz ~#jUd.Kw|s!HǣjU7ΐfvY1XMڼ@[VUy fӭj75,M4[ 毢^t]- Wx0BᡈsO1$7̓}VŻBaxb67>Nh-Lxԕ>y{X1cܛ&3p' CLN`3G:w>-?oҠ=_cگ1O럘' `@ &. B*V EU^ f %TvLA`Xs ~ : `W`sĠ n " Uq J!T aq: a-!` HdA(H. b`MOa`|!%.FG\ |a21B8B^ R/t@ tB)e+L@ -(M)%0-L%"$¯TA"mp(Lt`ȳ \B٢uh P1E<ʢЊ!}4K" ɨdJ|# D62H Q%}> ) DQ;? 24PXRB^$Fz-^IEDdFHa-OwiVeW]FB[Q_Jw DjO $}QI$O$Pq5@[ؙnayYk͗|[$W[I|5M1`lyEe]ZeV.Ė_ޖmX~ lYe`!xABIXAWbX(ppiYXa2f]Rac.d +eF %bQJ&a^h $d,qڐ&FkJI2dzզnQ\Yp^a.E/!XyINZ0!tt&-/T_V.fbdo^o D\U [Yforj-q) YRLeX~ҨBbDʈjU(LK0jdJŪvĥzIS^F +Kj*f~īHEfƵ^Dvr+ID.G%KF+Lr-AEƝ#"-ҢDnD<ʣ% RѵsٶIEhB5Dʂ! QB+lZx%J $^ Ѐ°BLR5X Œ5R+F.|LЀ8B*3*ZsE.tT,`܉_&^O0 5^0%TA(~cCE" ТsDv" 돎S tv*x, -T#EMB7*a-TA0xB"L7 uW?ED8B07qSlxwEh70H\A5dFh!lApEHG/lv-G|3ƁcD($D_@#iOWyChura8YAG$bE@8}{TwDǡ~b]AHElZK`Dzwϸ-.̍dH]]Aܦ7AB+>[Jx`yD@0]yUI%zWpY9Uy%XwWٞA$Wu[ZݽŦ?/x 8E1vWB$d•,}V`A)ijEX[+[iOoy)}ZbyGt:^X{C%8‚$Z@K% Z[}8A{=;|vMߛWaAW{3I]y{18DYA%mYE 4\[A%;Sze\ejE/I!+WӄGz+@t}ɄmV =)}g ܢw|[, 4. %(Z %@-L2.tĒN94!TPmj?LDmuGIaU*\SFK!9_#XaUdmvbZveM^D/Hq-s1iwSd}W"i{ |׀8G%?w5ބ֐]gv`nӅ-θXZX51d>7[bL9Mb鸕Ro$(SH/zc~՗/nKBf`+S@h]}s!$d1)i eͥKBXͼ%ߣ ,$ VxJ$2%"A&PD#J IFE+R`:@!D)Z$ab B[L=D%"`x(-iA4KU Pz1b h2/Yd< b8a-@d%xG#)J(xKpE\) MZ~V!F+#rf,"Hъ1SI)Ŗ0v&+){_d eKtXNKԗ,d_ gM*qH$g9E .uNJ>H+.F2V1ub)@D1e"I8*ł7ːjv# Id ҽ%Y5_dK]r(d{KX@ȕe-eef엯Ѓtabc%1)! W@X %yŶ5CʉdbysB{,os6 dd.3fdHV0n= EH3;9M񅘞 `Hx[ߔ8ڠf8,|#FHAC˟] P T3F'*M07otm4kdAȵbVhW$[! U՚FɳfkۿR0! ڽ+s7k(EhAnt;yNw~荶Z#%dnf7cWyG{KXn'Ο 1Հ $Dƴk'*$rhԀ$)*VHfICjO6Cc+L'FRL 2-C/JOLckQ! ~ZhJ~!U" dքBq%0 )Lpaгb+Q ~J"kGK$H%4"KNaFZ;i&0&(V1CHo%GRQcOªrH I*iл*i>ʐ1,L0 FRm%Ra\%AOD"-~Q"zoȠrHH11>1<ғ c~ (6.$*,$*Fg&!`:u !' JKtBޢb%!W2z>䅚R"") qN&Ȁh#Zq)$q$bhW+H}ڈHch ކ2w %Q**h*PI@0"s#0%S"RBʲ *SSH+R9xC#h/.:~6x>~ !H/p+,)KG%1,pb4Ӟi|~p9멗J+."( %#A~HҢ:e+ L.C3jNT<BѮF[BqB!h%h #D!,/XȢF~J$#1*/BHe.d/}Am6$tc[b>LX#%-CMSL7$+NsP4T%pKG-KyTW?Ckbj,Q3Đl0TTQ^i>AKU GGPt#U @"G4WBΈ, l WV#Ir*@15K7C/"«ý+pLb\xlWOZ54TEX;>UHȎzA^?^ {c_C" "+IdCF ^y9>:4caCaccMdQv6v|:9\V4fe6ˀfo fuf窵0/gVh?N%6i0M)^JEI&X6|jnhBjpý, ,oXƖll8S0Eή,F{7|{%z7w[Bh#7YB 7r|xW9 Dbc=hVp-(la vAx~F4a&45R]F R{JR(`}{ LM`l!z7n``RLJ n#74LM F):A):C(R!8:a,&`8x!AJ$ؘll! V5f-6W%!aF r$dal!<a /P8L(gBgCJFJ,A\MZJȀBJA?$DT` fD9$PnOQEPQieQQ"O( 9WPŚW_ @Vbxk%9zlI`+#/s*4=?C3$!I}>bb>3,RK  8.N!(#tA4"$t!H&[aC2 ¦WIj*.S"b0i2U$.dά::;4p(*{z)4#Z;eigenbase-farrago-0.9.0/doc/yworks130x80.jpg0000444000175000017500000001001711173714170020345 0ustar drazzibdrazzibJFIF``C     C   B" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?P//`{V1]\go$6ȣR}J׆G۩Y}M.c9o^u&`&2ǜpu_kZmR!A8aYfJh4O2l&ֵ#5kԑP"n]3ZZWh2X}(G`=kcPߎ{9m5c ,`lnwq;A`VL`di9=~k3nxNm~>.,6ux⎉Yl/cȒcSC~ W]?:e}R9ojwnR<ȯ!'p2%~*-&/ťqĥ=a!Ծ+{_sѡ]RSt}?:Zxo ◌cҙ|#]4]L2Uv$( n:WUEP%+τ>-_l;Ly` s$1+/]Qeh].DX䄍R%gہھX]WƗ;ҝu m246:WdCS^bE̶zԩ\4}m:r֥mm5^fIV>eu/]Я/n.a_%5x[?4j$fA&WlBj~;iv~KxuI*زџjOi?Oh$f4Fe >mۘdc#=+E?c,*Wr:N#^IoZi0' #jOn}Ϯ劏cbO~͟E~/PyuU$XxPF' 7gx◄>-|u: λoPpѴ ?xW޷pEum*:8 Ed[V0\*,xOY43ٳgrT<9O h\:=']Z8<{c>]5iZG4+s@-3*Zt:=χaiaIy <}ܐzs~~,YBOku;]EA<2w 5X~-n=80#&9#>w 6os'?zoa^k)JɩW @Qp/w [^.1Yڽ$'^tZ.vڢ.ߴx?F˒NKg zsq$BN6չx2.Z2R x;kp'drUsx+ ?[|f-bΧaUx"qqm X:([0:mO?ʮcQCmĒ[QHaEPEPEPEPEPeigenbase-farrago-0.9.0/doc/cygwinSetup.html0000444000175000017500000000537611173714170020744 0ustar drazzibdrazzib Farrago Cygwin Setup

Farrago Cygwin Setup

Here's a description of one way to set up your Cygwin environment for use in working on Farrago. There are other ways to do it; this one is known to work and allows you to pretty much pretend you're not even running Windows.
  1. Start by installing (or upgrading to) the latest Cygwin distribution. If you're planning to build the Fennel library, the Fennel INSTALL.mingw doc has more details on particular Cygwin packages and versions required.
  2. Choose a directory which will contain third-party software and the Farrago build environment. For example, I chose my home directory, /home/jvs, which is on my d: drive (referred to in Windows as d:\cygwin\home\jvs). This will be referred to as the "home" directory.
  3. Create a "mirror" directory outside of the cygwin root on the same drive. For me, this was d:\home\jvs (referred to in Cygwin as /cygdrive/d/home/jvs).
  4. Move anything in the home directory to the mirror directory (nothing if you're starting from scratch), leaving the original directory empty.
  5. Delete the home directory (rmdir /home/jvs).
  6. Create a symbolic link so that the home directory aliases the mirror directory (ln -s /cygdrive/d/home/jvs /home/jvs).
  7. Now, if we ignore the drive letter and slash direction, the path to the home directory looks the same regardless of whether we are running a Cygwin program or a native Windows program (including Java applications such as ant). This means environment variables can be defined just once and used by both environments.
  8. Install the native Windows Perforce client programs, NOT the Cygwin Perforce client. If you need to use both, be sure to set your path in such a way that when you are working on Farrago, you use the Windows client programs. The Cygwin Perforce client seems to get confused by the symlinks.
  9. Cygwin sets the PWD environment variable with a Unix path, so the Windows Perforce client can't read it, giving it trouble finding your .p4config file. You can work around this by setting environment variable P4CONFIG to have the Windows path to your .p4config file, e.g. export P4CONFIG=$(cygpath -w "/home/jvs/.p4config")
  10. When you create a Perforce client definition, make sure the client root is under the home directory, without a drive letter (e.g. /home/jvs). Set the LineEnd attribute to share to avoid problems with CRLF, and also set your CYGWIN environment variable to contain the binmode attribute.
  11. Sync the code and you should be ready to follow the rest of the build instructions.
eigenbase-farrago-0.9.0/doc/bestiary.html0000444000175000017500000000037611173714170020240 0ustar drazzibdrazzib Farrago Bestiary The contents of this page have been moved to the wiki. eigenbase-farrago-0.9.0/doc/noExtensibility.png0000444000175000017500000000250311173714170021421 0ustar drazzibdrazzibPNG  IHDRh IDATxݖ:EpF+s.Rƀ !=U%ّypW/ ! H ! H ! H ! H ! H ! H ! H ! H ! H pi෹< (;i' \XcuxmgAm8e@4]9~Gf>l-,)-xdm\ʞ79<$gNPVr1ԧ覈PV*f%T@+˭0C@$ AB@$`,ķ^Y}ݏ m^rȬR"U:Wߩz_E(x@?_lQ"teF  wn 40w_PRj}8נ-pO@7I@s;bNB&*qqlFaPC?|Jf-lm=zzoПR:@yl巕 @s`3l g$rL0 ! H8 X6} j3~soP秆H'1e:, v&!O ;]㉼0g4#yv (5lX=Nc4txq:)1Jtm?P1]fSJuF>O#$R"[ah ! H ! HsT**x@wV*ˀX28M@},jtNe@臀 ! H,jui24=iy<~oyݡo=,z}-勳jyyvSXT{|6J=f׭bz߄S (+ N7y@+=5I*͗\7 AB@$ AB@$ AB@8P0]'3.D@$ AB@$ AB@$ AB@$tN(t2):q:εrFs}:ݴ dCӢΎm+Ԕ2 t g3$ʀ ! H ! H ! H ! H ! H ! H ! H ! H ! HaIENDB`eigenbase-farrago-0.9.0/doc/design/0000755000175000017500000000000011173714170016775 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/doc/design/RelationalTree.gif0000444000175000017500000004671211173714170022406 0ustar drazzibdrazzibGIF89a1  $$$(((,,,000444888<<<@@@HHHLLLPPPUUUYYY]]]aaaeeeiiimmmqqquuuyyy}}},1qH`*\ȰÇ#JHŋ3jȱǏ +BQɓ(S\ɲ˗0cʜI͛8sɳϟ@}hѣH*]ʴӧPJJիXjʵkdKٳhӪ]˶۷-`Aݻx˷߿ LÈ+^oL˘3kތYnϠCMӨ>fװc˞M6MϩsͻߢWlȓ+_7УKN̳kνw VOcξ;GOկϿ4~h5Wk68 VhvGv 6!$hb~ a,gx4֘uM뗯܆+nڎk.e&Z_{VG+&oD^+K0W7pY?,qI hgSK\w,,qL,lr,&4׌6+s!s8,D+ 5M . 1 S=bC[MB$B`'0 L0kMBـEvƞh6q 1$8kJm ]᠏5xޞ D=%жꟻuM;;G 6?{8Ȏ{5Lgw8ߏ0gưӷ$2/ChcV36 m S +Ƞ7z !" $@PxeU%|*ȷ~sCI5@ yc7{[bLX*ʰYGāH$Y\JX8^} mAHq%6@u8X`xxYhŎLlW@n^ Ĝ7 | <;6F\ .o9т 3ґ3,V7_>|&xȺ] H5?T 4Mʕ‚w(ɼy][ >Lo febZ{dlGKQ Dq9x I9DtK(n@t?+sR L&;3qr] j1JAιv=GKF@RD % >i& F࿛&78 nNZM)Iѓ)PoW-W:HC 5&%` :z@ prV T@Yirه5Krb iĭ ׾MjW6QRЍtKZׅլ6pH.Sٙ  -mn@ޕkہm yd\i`ӛz[n‿lt= pSǾ [ΰ79 iB'S&ޛD #Ik6+7ws @4r-WPs5q U:\ ~Ruk\"Q'G틐M:UHNץ. ]'>uO4+vvm^JFƘm[de퍨 1;kGTzc1Q#Mt `K{dxhd3zq7XJFW{G@WyC6`@xsN'7SVVCP>=8dz1WY;H5>_ts_qC>YW}czC "h;w_msJǒB{5qXi؋_c#C+7s,iFahSe_ق>Ԙ$`4FO3i~"#j"`yn0-/SoyeG6w7i2Ճ*z+Aɢ*:J)T(dD7F7 TSӓ$;@)ɥD9/25N,9Q;7Vys5(:\U 7$R1.t'`,k,ed ҳČ%z ,rY 2,,,g%-\,IZl'}tMزȪ-|&9M4]K-8-}LR"=Drbֲ#P*Tm,'wul.BmC"]-+@՜+a-v. ł;!m(@1./h.,]q'w]ٖ}rgٜٞ|-+jR"2 4 ~ڰۯme+}۸ۺA+-khmǔ p={l-A|nygQ<@ R&-7qCkoLQM05 d^#G91qC-/Er}/,>!/ck(#f $ nQ"kUVCr %j<㓱`ɍr@~= DI] &>H<1$n8pʫ^`AB hf%`R^T5Zҟ")$[oqY#~=4x1SmZڕr3b>^~ꨞꪾZn.>1;.2-Q>2N:e&s#뷾N4p:n-/̾08!.-ӎ12)Qbc2(!+ S#ƢzCbBK"s <;&CB#l/a66zU04Q=d%A2/Qu<+.a C>l.5S_}N/$9cI\S.l:FksO5Qn/0jo3lf37v4q8wL[>༖ 3. QڰCǢk:*0C 9-iHT 2KӲK/Kl)#hp!{(tH#ԩ"JͥB"K@MPTD`R7;Aġ-Pñ.U=-R$ӤL3W]sW_Š| %+L">BrMnJMJ'hO"̅&+,Ȫ=pUlٸ̖jQ;-L"- wk%ES>O݊T'x[[7VwMSJ6c_ոc8z҅bHM ,i+.*.h jfF.䂰RM!41 j !WW܀[Y ߕtCri:"1.-j$n^cv@`.c ypÖqc8{̬ܻN(Rn|۹ woS3~j7<1"Ð4MS[+vlr4j/N$j*La*?n?vVG<}Wg)+"z4+VvF=H&*կPcRw>2?B>̥yJ .0i$x >PB.` W@Ԝ )i#×&NxC6aL>>݁`KlD -ܷE_ܕhoFmr~N5 !W|$2A+Ac\dmxZ4d""FE62X222k+q各pum`z!A{Yy @] z 2I|&%9{ZzĶ U<__o&!{ RۊSy2[Զ? [ Xfa[XF8*5ured5^~񄾴ʪE@Kw rMb͆bmU3m}v5pxD˓q͌<14t}|І vÌ,ϕ $cQretxqN:OZscnm쎬9bn2*oLDŽ/ldm78_z)UqO*C%>I{?KuMtcv'21G%2.TjL e bFQFŸm\fDD`ļcDDlFa$nFPǤ@G_3mGNlu{|wEr\yz\D}G HǣHAHk\5<Ȃd\FlˆH*4FDFTB,H<* 0,FLA\G) F( \-4EE=@A5TC-CU>MEuT:mG6I2KT.M*OU& Q5!-SUUMUumWUY[U ] _V a5-cULeuVlgiVkmVo q5,sU׏uuW!MweyWS{Wl} ؁5X+؃UX_K؅uX&k؇؉X׋؍X؏Y,ْА5ٔ}UٖUB8ٙY0ٟڠڡHN ڤUڥ] (٨%Yڥ!ڮڟڲe(ڴYmU۷%ڰe5ۺZ[ڭ۾Y[m$[e[=ܷ%']ܮ}ܴm\Džu$ɽ\ܫ\"՝5]ԅQ]֥ݼu׍٭]_]5^=Ut%Y%XZO _@_ZR_^Yl E_Ez(p v`ZODN`CZ FaLMZO^D/Z`auaDޢ^bDb4T%N&N'fZ#)n*btbb%01.2VZ.4f5fqcq>;<=>&?~@!]2"FTddFGƥHZ9nJK][deQΕRST^UVv/eG埥eZj$©(*'[ P(B`>\.Fd0%ٙ%ct㽾 "1>iΒjVk^^%pNE fuvvD_)4 ;+٘(H HH"fx x+:'J I4>HhCZ R }ZR!덗. q ji! Y琘.i0 ꏱA︛ p&0P`;}ދVˬI4hHIknx/:L氵 L1kS<^ l~Kã` ulvlGa'&Nm6lFY*kH&B0@* .nl.l3a=pVQm67Al" PnL>,NnT^n *ȁ 5xĿImo1np#(  qk)ʫ ^ ޢ֘.5y86A(%xK!i! 8c;9׉,@gPhrRp2Ynq*dN*0}ٍ~#~ˆ=d beKj4,a9g !w"gCWO<_dR:;eYwM .Q0 O-N$I`v)c+<_iv_5hv)@N ` `vwwxww @ ]pf[G"B) # wuw (sOuyGN|ge}ג=Plhjv\va(Ieg~=ʉ6V#(v ` Pvw --w 4  /%J TW^yΞ3Fyz XgɈ #N{ȴbYx{/xy  +ps$ulOo_ ؾ.Dg|xTk.|$A !k@rЇ/|AxNQG WG򺆠rEgGꙒN}wk ihIO cofz'p,h LLJ @8thP8p(HBl̘2c^&Μ:w'РBz9(҂.()+JLj(Zr+ذbǒ-kzHpB+\ Ե E8l0km1آ.mV! |5ТG.m4i}NmU 1{6 z4H#nXn}♌S3oU1='ڷs{fcDFRe.~;u>G߬xz% @n Zx{bx!V- Ud"-+vއ/ڈӈMM;x#A d!Θ\CwJ$UZ^ XWw( cJ%iZnXkbMY'yT܁{ZHdY(&WRz)V2j4A}jz*Vة:+J!,YksS ;,Ė櫲,,h*hbKгz-R&h-im媻.N"H.mˮ{ocJ[/o L|0)4`Yb% <B Wש-o' 9Z̑AP=3A =4E32E+4MsQ/Jm,uW.85]-k5e1iZ~o^6-,DPymmJҐ-P܀C  K>yTx$D 80⚛x͘,@5dBc{;0DA? < 7` 0R0d`O}σ' #D??Xׂϕ :` M~1.C n,%p\d *=Z64~nP(H+!s<<ZFz Z1;Nv</"?FcFHHL`4&D:G4 $$C^T$A$v"Y7,ZF ㅡ#OJa`d>EQ#F"]ooEA$Oر^&@U6D&ΤBeSR$YDPl7&D)"]S ]Fŏk!C"+D=%iDD ;DkRU |@D&mRk&㕅'~ʍ | Omz^Jty^=ޘ&-QsF˽=&fM}l$g犐縙{g'gg{@;R}n}Hiž~^S&b ˀd1,(R$P~Ѐ<cigtp(c| m ؝w@(P@ gTEDo>3??3@wXzA4B'B/=#D9c 'Ƥozv|L(G:zL:sz 7ˮ3xzK+˱kzK?FL; g{n~ wt3h&mqN\p]PhfM}fر#RDD 49`>,仾';UA_-QY&C|ģ61*N e^i 7Icg\@bDp.f@ AI^ޞ(m< |2zކ猦ȏ<> V~v.BLğGEaݕ.-m.هt8DE>]XF#BN?0Rz5L+Dln~D<Jev;//2A4'79aqr+ SjǗ?~}wf]3x . :j[;8ͭ >-?Co J#J >*P9PNB&{x R! Q:K\FMSJZNUZ YVW*KW^ YzUfM[ꞵSn]*Qv_K G~ a2Mc!8No%e1JpifAZL5iQZծuka[ΖՀhq{Ȁ;a?IР5d/X6rqKZ\(PLnq܆rxO\[O9Briy1Β&`5[Ɓ]/jG;TsK^lnAz9V@Ɗ^|ƶz(G΃ԧ0 ^`w0Zë\w b]E V\x%x]aXjxa(Յ1A2%)bA'̫hmY]G9ǗݱCmY1oW@hGCsgWNdI^n) 0dr6uT&((Xm̱ ":2T6(CcMW~9 M40вm }zAW~:^}2~vPv9Rz |M:K{W{_vϼ G^5tON{~eO\QOzvcgdr4vDOoLЏl+Xƌo4/8( 7B00 ɓd/BN( N^n~/?O_o0 <0… :|1ĉX1;z2E$2ʕ,[| 3̙)$͝<{i^:=eСLqM 5jϥMz*řXj5^$[صЖbM߲T6/)^7%_x4p\t:dQbm 3d;{lY.r7s:hӬ_N ִ#Ǿivگq.{w޿ .4q OyyvC+8֯^˛>}uO{{#>oɯQGӀ.Ł`^8 M J!V(Ӆ~8ĆjbR8R&)bJm2H52c3X;JF~@ZoBH`G>SE*䋅6%ZZpYT"XeюqnJ0yrI'zF5nygl~e&%&)zTuY~5i) 2ڀx噠z^A "_:&AWPy"Pz:f8%엑jʬ kjJ ZϷ%D+ '森 T9Yˎ,ul|b`/#!+þl ,oK 11?8T4hX'PpȲCʖDL$.̊,s :A3>tB]'vt K3MmNSXdGLL͵VvbHv!zE-1n+6CwC`wxІnk"yC@񍅴g R}:+>v^Nq-C뺢}k.#º8/{gCs$so@_}_OFXFӷ#o3gqA~` ?/IdrhLpBqE[BB' -̆x w\(eC/,Ԩ&0U "bB $WBOf?fؐb*\bA!rA|JS\ja$"d0J$1\gTfH<S](F3Ǝs!=4Ȫp$53LRl#Ɏ2#QD"`hoBr9_ Igq1-$HNQj,QH *Q)YG=*R\"2q4Dd11 grdKTd;+viYfhwF&=rMlҕZ<|233=y riLEF e 'GQj%`Y”z|&Jg*OX2҂K)P4S (Q 'b"+E A|KELtWP}dVϚM U\63hʅDTIu W5R3D$a:4Z @vHlM3t~jYGJ6d[C*5gZEڞfA='ksvd-y:о6`q{!wpqī}mcKF:`.tJд/]R7af{De-hV\,M ^&Ǽ;Sp-K`.ᐌddHB~t·섏9L(}|Ҳ }0?7yIԄ'gUD60`Q#iBcբ>-oO84>wWTg=>뒶Փ9s#f4g$1ίEO8dbԳT[ay⵮".wW2'٢Om#ZF<[0+XsvDnY6\ lu{EqUbWFg?[L8fJH0Y| {qj3ۺKM2|{&<yPV1n08_[Eޱ4g$] F fvWQ;"$#JO#ݙ ہ[Cݜ]Cw'N~g8₞(iJ}o[vx%^ӽ%6r_6qkѪ~c僟0zs f?J߅ENs/avmG2!LXKzJ^~f@s7uuV3(s7(| k~&׀`3.ʗjߗ# eLTw@\DgM3 {GG}dIM)OZt  x6| =Ӄ^d FG_tV6MGTSHaXqn"xGY3 3]eobX-e1vKa'qbo'fHAX0t}fJ`Et}ZHd0f5~ǃ8qR-y&ғ(f66A3RYm"JҔ!IjRH0Fj<9"VDQ.U)7 C^DqPXg Ղ3/ɗ.a-cċK)&y lnVǸeXSɈ9){ ITxyvx:v968NkyWVhPƙ9"#YQD\1v)ؖ9?ٕ)|TTZO{SvѦRCr77NgJgGE9lɝ-IyqYvWrY繍+隷gg؛Nv7b=xikɞʈ`6ԡJK}8{@iyeiwbXYJGaHiVLf45: 7ӗ9CR٤ycdaEWL djɦGy;ʣIM*}8J|ڀVJ 9jkh=j:ʨ2[*Q38J'8)HzYh١եRZ*r|pzJF;`zZh)C ڬʘ7;C_ZpIjY/6wixʬs *zen7ZSqZao iJ窎zQ ;E|(0քr?htg7۠ڱ_-DzTqeJ6EtHsc6V2Zsz3kj~[qHY(?!T,P,t$ƒ{gqഡ"+1J(5'sH^5mdI3ʵ3j K53iʸ8XqT7Δ'+,x5w- R_]|ȳg,>q: :je˱éĚ{ܵ K +Y};z?ۿ;*^;@ˉ[cK!Btw/+ gP "ū2D̮ \cW\C6+JQkN@NfW-ө;xlq጑J]6hT;Q[~Md%pPfo} ԎgP;Hwؔלg q;$`ֈ8= ,ډr=lڞ]T$1 c=},ё C]Ƭ$ۼRM'܊՝9%ۍXݼL*-] ]@#H һ'W+K+_硅u]LSL>q:rl|H .?KxmumGFtR!.@Z+ݹ miZ&ݦkW"~ЖACie0bVބY]+."\勍Ve6Zw 9m=B+4N92jwߥ}T=.ct}{,>Vu;I;ߴ:m湃^TFAЈ-;+npV^ ~ὺ>å޴$̚9W{nnR#;^8z%=VP]+Cߘ8EMɊ`/>. ͡+Ze+7 qϞ9ͽ1خ~p'Kء9%be< _@ L /7ww6 BP2?Ouz?)7W~ RL\xwa)FU ~ɼWP2hj\wD,pG_-_]Ud]c8ϞOhn_$.FɿJh= K8ABwpǷKT^^@cܗvBMO//T0{^ȲH U(G븈N1uaV{qAtPY:n'?k\_vq~8kQ 1!## %35(-=?07G;AOL+TDI_aEXQikuD]AvOrwBMrufmo=cI%p{}d;礫/ʵݩz9y7_-ʗw0n]E: fu^Ä+O`@(2dn`ԘQM(ZYLDR`Qǒaˡ **>ҺkW_;lYgVU oLnICBL&[4ݩk/#paÇ ۺF#^)Sxyā [\ysW!z2ձgn|ڕ\?l+~/_CzGN=|z~ ȿ*l͑ 1BP) 3I,QN:S-"'|QK(^ G ʘ9#Ch&1FL\ :*"_o:ܯa??#ut5Uπ <u!΁T>Ȃl$QЃ%lP–+3 mBSo$ń Cވ6[>5$DqFDD*PNC0qXF8 e|G71&@&6oDGHG=ŽcfH $BАt$P<>$xJ`$4I:v\_(EFRJL+aBYk%`K]/La;eigenbase-farrago-0.9.0/doc/design/ValidatedTree.gif0000444000175000017500000006576111173714170022216 0ustar drazzibdrazzibGIF89a"  $$$(((,,,000444888<<<@@@DDDHHHLLLPPPUUUYYY]]]aaaeeeiiimmmqqquuuyyy}}},"{H*\ȰÇ#JHŋ3j1b CIɓ(S\ɲ˗0cʜI͛8sɳϟ2e4@ѣH*]ʴӧPJJիXׯ`ÊKٳhӪ*ŋpʝKݻx˷߿ lBk+^̸ǐ#K|-˘3k̹g_ LӨS^͚ϰc˞MvТ[ͻ |mȓŝ[УKN$qسk~yËOӫ_w˟Ov*ꨤi~*n*rj뭸2kњW+;Jt챙"F+Vkf 0[>]ˆ{gknx ܸv뮔RWѵ/ouDoKȰs7 +\W bq1j\ry,r&ɓ̲d$ǵά47rΎ <jCF+[E'M^ӨA4YHOPZԦqWU]^\ٔmvOanwdsǍSvww |τw=M;. xN?Q.yJF qAr<n -L:~N G -| a8<7. I,d}N$H)ӹp k GBN{qc 8`HR( 8>Ѓ hDՑ(Tp `{>}d  ~hddAPxHdVɽmr8 H/{s G;aHEgN3C4HXz Zy@t+;"32 2qpZ$%@!qfYdIw5TaP~c(-'M0|  D #E ъroiF1FY Rf[ VR|)@2EItF*0’jAY~X(CI^ . AšrxVHR@ dҴxͫ^׾b <:qj#-w!߽x SSTFB1%3k% Ah>␩5AhRH3I%~ pK⒠#E :ЍtKBʮv[-X(@ ,k f+G_/ k6ccBNu8]8uƱxVTG ,B %/zd) Z`S0Kc谸8α{yci1}h B[vm% S@Kgɿ=p|2AHͣ_~ǹ2p?;3ָHZ+]A14_}v+ėU`r9˖<=ȩ\rDIi@L Z=V{:Qztr$@J`u5(>6ҶI5}\WtJ <Czuzc\AdV>Z܆ZcQ6x4E@+U^^*4TvmT}c[@AkՀn$~/(9gHHgGLS|!JZHP|8'QuM#km4>!AOP3@t`]hNAu'=h}gZEV"=TQAujF^6vO{{v~'ID`(7EPKVeVe9gDc ?~CKGGR؏ce%}WC=$TvH[HG_2'em\XdX;#s':C7M=`h|ϘH=c臆]cu48ZD#QN5=4J4_yD[P(1Q,Ք!f@ 5 U)JuJb^H087Yum8xhC6gd>GC!Ď-%pi79鋮Ǔ9(yCzU4Ne^T;&Ew䗹:"G*Pŀ^>;gH&9Ė薨76'EEt><,A)4t{G|@FV!%};i:xwIL}#9 %n։z$j˳dG 9lZJXj# ^ԋVg)楄0zUYBDȳYC"ySw@JVJ~Q,آW; -9P7l![gPAUaA#hf1cϒZ%}ZoJvbqQ* z c*\+[r~E>tz-IFy{34  `."):Kdea&Á@Ukج޺60P0Sajڂ: $?Ww9@ (09@$"p65zK, 'a@9ua4,,*Z")+:5N3,? Q纲(aHBA1SG;Z%ʭZ;%J2X[Ѱ, ɱWw1ik0. 7 ˷T0{Q*$4a!Q/hZw1*/dj6>K=Һ l :!7.,ۻ]᷀2-=g:Z+˼>֋(`@1{9ܫK<";^+9{[9!?  @#;^Au {.``.0,] 6|8 ^ 0Y;0d6k6HJ86PR16ѾgjQ!`+V 4]a<*zƬr ll)Pq)`{ǗR‰1z\*uċ Ȣ,%X9 hd^_4:;)q'PN!QFU:>YH>4|$i  5@_d6QRfkŏ5-O:-<nFl^RF>%-f;2ǓV&dyM]Efkɞ\T%| *QC$sla9XKU@訶&Ъڬ"|<G&I˻XK*_b gsC8xTA t~`3!O]e@ퟯVݎUL^cI=NVAGfN fVjk3^-< !ɪl:5'aPf'Z#A J_? v,|Y.̽Gr^. 7pv|7=ᴌn%@!`QԡhŢ.,*;RǠ^0{9#;*!/yL{^2v(@'@ <싵ɣIrz좕M^2> #a~JrEIzUlstU%ḿRKJC'|в4>L6o=腉 ?\RBS4uΐY-Ryw`=ACN !۫ ?Z⠙x\T~H_C>l'zƘ"}<= S&a۽5k$EssއEp?G+- ǟaHŜl)9gvx{D_*C@ DPB >QD-^Ę =~RH%MDD"A 1$APG eL- A 7޴Zs`K=#'͞BhݾWܓ. śW^|)$ 1^ Z0\Oo1tz c C 6 R$v\p&zG\r$@Wxn]ue<@;@,|eܫ =pc%,HӘ# 4@ dAs'j8"O?!'@PD?,H@x! SLhjŁnjDB D50 8pI)! 02K-ˋ(PKr l3M5sM7߄382 ;(qOAE4QEDs `QT`$4ӂԴSO? @=K-HENReՌvafpU#8z-W_+Wa Mb)e=:0686[OMp@z!h&Գ\uBuߍ PxA{+"Le[&Jx!݂ v3P'V(I/f.Y "AґOYWXd]J2św>[oPշF棗H^zZ(ZVWjYfI(~f;!9m=Sn_e`n]NVo!oVEl-/MӐ_z!/f1o:aVkh)#A<'脿4+J,*: tQ!,б]O[t=-zO~Z=0i2d`E`N|pM!0X<%:3] _ϔO׃/tБX6Ik4VG1 zz`(Ij$$EP|^"d1NfCb AuEM'VYЅ c]SZhG q !̀CV l#'9?;vLEl0 `E=#!Ȧ0k^+Oy.D '_Rvb2Z\"@eNQ%WHr&bQjg2a4Ө„~T|tv2@%0$+vl] N ?=AURAGA֙?ȃyg؃‚@kZ#685Ћ }/OIf}Nzdk N,n @ir"Ox¿i? [CŎ, / B?{Ձ 5ֱld%;Y:(Yvֳ Ȫ)`T!%֊$8 GN L\PԨ3!lTYʏ Ga <;]V׺.6S7@@kf1 tG*HQ㘁 =uـ(C5ߙt&mc(p:[*gwT}SNsdZj^Uú*.qe$BGGd\rx,lT=VR Ǔ 80/Jˆ'2HɥTH Z*:^ġ"Fe{.:%_ǓAˈ'(j`% @wIˈ ѐt8Xˑ: *ɉNOit*;",, <(Qd,̻·о+N=<Nj'JM$LFkPDžPPMG(<4c%hQ|JδE MQxPPO 1RL9? ta y\ IÞ茛h+d|6L҅XR5y ӗц(9z:^jġlНXlc 4mS7]4SEaP)͈p+Ț{SJUg<T"ԅ6U/ UDGLD 2Ś*HLZa cfUYejEU+\փV.=An؀(ׂ9pIv):E)V z ׃W-7>:S؅UX`؈cR|΁ՒuRD(Y=˂Eٔ2 :؀-Ufقҝ= M}pkSڌ` Z1:pň*Ll [Aڱ۽۾ۿ\r!,ۼh˺;8C\P\xƕ03)](}[Y˵\@`+A $05[M] paO ݃6u19ѕMu^^)H ]^ W1xY;OVJ^^ ͈&5p%mwmMHchW s`ZT ud\;O2ְ a-߳j]*l*c8c:#` 0`0Zuc;c3p AƗ;E6Nb&dcYD NTacbAOd`eP 0bc¡Eke:+(Sf00Qe4bhc^y] Xy(gM]րxꝣaEa 8gg;޶|H4N])L=$P nnūmshpeYe]9Dƍ+!`b /mg jfahTɁn^XmY鳐l6Mg9W-%DPٻY_9kHkQ*t 3[iFǖv̽G8gcR=D췠lp뒀cO 8AUvii-Ɂ@>jN7;(esbdHT)579nHn[fę.ZΔNV잋߸ oVᏨCxɩ/bR/@o=aod;lw&c~ ֈ(J БROQH‘ ΋l֋F |,j +׋69xՎv !6kX̀)2# ) q e n޾oB)p.7"%; / 0o3cA΍ PLjȎY̘؉i:=> ?GŖf tuE(*ءS?tY7F_Oۖ0C7拚6q(Nw`:p.ix0j8uAAc,BdB׀$ET [G]kFn 6Wi Mۺq>{< dyz_0"W`E)pH889,C@ 3̆=xq"sz9sHuXsٞyp7?"9cƜp')A'lpqLxW({zzR(uiyжH{Yh{ Ozjpv\e& 8d_W_mG.ywv|DuQ*q ܀%}6-9j!r0ox{q}j_ݟnwQ^gt_A_ta{= ύoɍ{ A m,h „=j$(!AC],i$J9 H%̘2OP0&Μ:A B cv mZRӂ@L"S:đ`\ْ,ڴQ]@PmLh%Ի&Ep 6/W7HpCŁ::zΎҲ񻚓39;L0"BTMt x{0,pVNJ}Oq^t`p48Z% G 5@W Pl5Fd&HW" QB(ʀt(`  BQA @JcA$2ӉOR  Y9P; 2)5$q!3Egȧq9p(r BJq9f:%P@tn+)=b0'e$ $j'" jXp{eʕ9ЪKf bgCv1 ,*k2YM.Dd1C @DAEV`ޔƱ0eUǢ68 .IM -"-0௽t V"锥%pS7wҳ=Wsg=֋1RdQ0qrZBzI,`@@sM١cGB[UV6-7_ xP 5"W$(wyڠ-- k9{9o ~:(L:/@ۮ?C0٠A*?Y( }2178ྔ&[5v ,|R>LG@"<mGԉ4f\7[_!g70Q2 `aV,?g`Ao%=(Il3ȼJ@Lʚ|}@"yDY*łeTAҞ ,e MI$]>")-2"x%k,xJʊ@UYr[=d0pj6 vӃ-JDGG=g-ZPEx`) (X,# F.km[ ܃bd&&z]!S TGW {yi::d>nRXV!qckYADS=P[K PG4ӶnE]<=3|-'%9Nz=/U)uP5תΪ>6rTFG>yWebAg:ŭ^0jx̕qI쌑N7iy\@ųV~uOҾ=pKģ;*ZG btS'YWZ cyY:/t!E[ZٖHK> HW]V#A s8;""oK xӼмYdh0戣oh LsR|fcV9P'&.:J}*KMdm {PylL]=e׫]Od<̼yjodZ tU3آR."gWx GF[ۚ~3/=F58NC@B@QԀ$W+SnUvUA;919} rpr>\Ӛʜ ~*S/?=JP:/?}>4|_~%zC姎srQM @@qDSDFJy@-Pp_,AZ=G\ J޴`T h\Qm`*Ala >I!tƩ Õʀ vIɜX ԢZm,e@ rKv I> `Ƀg܀!h \YPAߟLR#5@MA@88D t޽RE(*_ܬ@5!J %P!!p@, P+@!)hzbUL2V%r1zL ԩj N)bD,MDZ q h .Q!@L1rpG 2ArY7U#Kc@ȁ=J9eua2aB\X@|@WM˵lX#@ƘL.@(M @uɊ!IqTRnMyTѥi̜Ch@^HEV|ǐMDS:PHK@@ ߄57MK\Q%9=[8 nFX{YMŌXFJVȏ6rYH8v H^h P df%W8KQCB*S{` dYwTBl%WehYpXlf\ťetjZT!fTaU DRoRUu Xj$ rFYfqݎŽb%6(DF8(zNWf H~·feH" U3& c)fpfdU|}"~:E2t%B0v`<铞V` Hv~x|)DG]8TFɑnzY& ( cvbAiS ipY)\t#UH&@jBP*G`*s$ƕ K-]z i:*b"CW$*'P)RͥEtI*oټP$H@kgX*Fh(0*BF:lMN("½BA)J%du Dzyj%X@gz܆jJE ͿZrRE_f1kU2(gB%|Vo^]Wsrkdźj٭׌|Y,}+AkGWj@$,_!(<$aYpPP"푀 "ym*"Ę Y,ތ!?,ЬBɨmgxm ^KLRm*b-Rm~ĖIHjE*&'֞ ,.L@-Bn+M"D'A.ń"ۦBEe Lf.f)8\Yj*FkրǖkGjH]bƛmክI.%/-/shjz0zVYjJ_ݕE]NlB4}#}@Jp^D$v̒U/Yޭ4oZ؞QMPn`\1m*SE8oIpT瘁  hT-0vkzYa`<i#VQ"DNK HXoIh0mڛTMPTj:-(6ACYO YD2FPE_% PbR@3X6gR2K 6\3G}.uTu;\P ڠژ u<3!6YcD)u4QxIu%ZVXCC6%^HIěZ{WbGbt0J5Z5E Hp7qq7r'r/7s3[sGtO7uW7sEǀߣ&2`RC۱%b7B7y$}/GTvey|hvu6ZPBvwwj[A6BDNG2"zɞ[M xK/GWX7pD8#I)pGPljN Q_ \z0x]FwR˸k2+6a\8Zxgwjb2CZ#gˑ44xjx|s7\Jufb\Hrxg%ݗo EȷGӜgf_}>za74lllEd9Ng2ZwmGK`:.t&gza>^&z_Dx*)1eFWuY7ǜ=J^#yt 5F9\9fu8BZD(<{4ǧNq@@ĻIO6eC;K@ &ʞ%MѶ Y@E;NB3anQ[SmԞEbGW;A'} mj|D:vL:wR^GE*Nzn7cՃR D=sMmCq:w}LWXpjǨ= ow}r<GI>e}f~g/Ӈ53  X槾e7|Mnw牭>2"+K SL$3E#wT .S96S~'W5lis6U$= H㇄{hci]X:ٟ@$8P`'0TaÆ&:1fdH HhRcI-TAZƜ(B7qԹgO?:4 9?|(y#2t1CJjUSHB\!* $бkW2duɤ+o|( {QNO51o;%!ܘwd 50X?v{/xexճwɛ\wlnҿDp!Ϋ#pdf$ml?GDORn3.u19#:0u0Q1rOj:ϠVjZm5epFc`']!wBx.RhHJbmqg_h< bcȱ5(1Hm%L\&j KOATH"%S<*r>{F5b ޒL A1[ !T9Jdꖥ+M#Oc+!gH@ P:Y$3$\tC2'6#])yd&k,2y@7uB;:Q"1hSI8Q/D ]K\(D m(`0QTwɐnRGsȧ#!prrҔUTIJ&'U:sz*TUO *K*Ӹj$3Cjɼ lVBN kfm,Jۃ~ld1Y`'g/؈V!I pȴhiLJXNdK 3ФZZ&s{LvIu]nw^V0 yћ^7E (nf" -`=Evb. o`wOD\Pa6а~kC6sEx0`}hI,qb9 87`9I^/@Ol(oٝAx` Bl,g󛏈Ùآ xsY@O9[9C9&Mv@!t\0 ϵe$+?Eԥ 4cXSdS:[ݝoA^Xߴzu:oKDo pS@vׄ;㸲Yz'լ<dyi  z(,?ܗ;|;uMl4O,sK4 СЀf+?'[g5򡤸ϝֽmm>vgz=w{6vQTp,0@Tz x,X79:u' H1|y(9a1 ""zxm=_" 0i{>|S&֞D{H`=poW3fual~8]ufK0p pTP NΈ+ Oln Odm.P=ZF00`e\J04Kp0 nP/QpEΌpo.j0n0 3$НbNfZ- OJ CȰ Mnn) Uƒ,d"0 "@!%c' {rf M.0`*( G5 '}VBX+IzbQ7,/ d9ާ!.$eNI161y/)UdX_€\ X€nI(HH\2I i3+sTj(@q"رO.jlVB@8)#ă{ `\B:h-RQ,S"*+$4nT&n#.8 .F';hDH"S%z@F#)DOLwHr(zkc _#kf@{p;,EnƐǫ({dr@jdq%d&$pr;ʃae3p,;1β$2-sZ.M,gH#f.HZ0RNB/0wAm1*-#36\5TMd"0#$^1|NF}nA,b0(^tR,55esB5Ef `4CzdNGV`/'B-rr=2/::11S%0@wٞr#CgPfMR,dBd8B XcMf*0g&G: TYERՊ#+iAq}R@a4ivCZgj` FFG{t"FrI] s^p1wIBT7 .tkyHJ%B/MoC̘PAtEMo#(bMSK3*"4,,ƣCT9W;1hT!$U&X!X6{ wP SS,.BbYgq(''1K1fq bb%+nY4%X2})1"]Nw1.D59R8U;ckj$'\u0:tGfunM V=*xHl%;"󞇃,I; ՞:)V'|( c2_!%HB3R+̢hi#w6 i'?(R!8ŌX7_"H˯R2^1^GbS4!tR&!Ɗ("v5.:g{_a32 <0 :̠0ĉ+FPC;z2ȑ$K<)[@F tl|#$>&2hH &@`aH'Х.$Xj 6HO50XDҮ4dTm=H(G 8 >8qH-:~ `9sf 0T :ߕA@ժ<Ő` E\g֍ Ӥ;ֱ$Z#A_e[gW>h[/_˛?>z5_'C>/S5@ lvHKqDpe7WGwQRA@ =T Zu]bih!$׆7dl5(xc>c{ X 4Jnր@ PR@S2x"҃n5#T2ntZ襂auUX ~EU7@si'L'=f0.eNJi dM@*h D9n4y@Z~ EݖG_1jSYj² PmG.$P +Zkש枋naj[Ш[i]~9BXG)? qۮSlCoy ůz $F!oxc( sM|q621y_ EZ"7:KX-pAF.LuVEZoY:_}^I:%ڂ H 6{PQ3<5zFYs x5yГ}&.MۊƸI ?Ny-x暿@[X⠓HW$Mzoݹ祾踯l黷HN|>{nwlt'/o=I+~7}KG(i~W@ߏ p, |N~# Jp/ jpP`8$, OJ_;4 op< qAL=zdDl''TCP\E4Y`ψFl1l1"tcbh<>z$˘> r!.>"R/ >1ܑ"+F*䑘'P撢&R|\+ CWvI,oVr.%.iY@r%1)_%27cBsʔ%3 ijSf1 $#1SʹX%A–ɦ7 ns4 #%Y$IR hdt0 Q|3P3 I"ϯR$EO갉 ?]lȝxLtpF-?с rҜY0}ԀH*u!-HRu4 #T< SүtR)Y;Ҫf`踪;@̲=*~,6ȲV'0'=QF`ٯ&yY?#6im POjU8rZ̅VQ@a2Rc-[5r,)j+ls#)Wk,4ݩ@yn*#2j-^ M6ti( oSmEElp+;Uz^`4*oj9 x5$UIXX΂|!8xVٻ^D5A28*.~Q+Y0^rSQ'*IԵ`C8ƽJhވꁱnB)-r+Nsar@Cv%K![1 ֻP lUji oPDq OldAuGh`=r-XdLd?.Q+ d^&Q TNˬ J[ Pư6aB_`uEtDkQXmZ;07o0N7;~Jc!G ׸KM eLP`%,o_|.@h\ A7vE6FR= >jLoӟu3}I7UHxQ#FZuJuc  lUPHkqX3r ȜԻ'-So&y!Xnp,VK$|0TC pt],@@D-WA izrϾz'VUg *eʂq^ K:Ī=J @ /4PC*rA#Ar6w6G9~7'U'^b"K*f-xU5b0PC&r+ Ar3TC>WB=X&6j"!Pg~'GxPug"2EeaBq~=D5$,4y Qyr(yB#q>҆ICuj#D(d2"wR-:+J77-y~=9[W-/$t&r6r|r,p}rcTw]ONZBqB=h}ҊD-',JXf}[4ӒWV4wk+8!rnt720-'HĀW5h7ji(N7kX刃xQށ8"'qsWU\oZR69PcC2@ A7r$`C"2bff1ic7fиAZWuu:'PKꧡQ5:)r a㙃6œ>X2R'~Uy)iIY{fɖ*zA8.1~څ44+&Jyy6t8cg!WoU)X!XrW'DEfVV!IJ:jy{XC̷A^ A0eSKdFS5^`DSA$NFW6hY}U-PS[Ųi k kG .@*=Qӧ?{<[G>+Q.++4P9O 1Q{$kơgVPFT7x?'QlTh6?(wg2|rH ok*_HEIrGCw FQ;1㶔҆{bh-f',*8V+%";:w`!{V4r XfK5+Ԧթ SUn;"(Xx1X%!"U~iV^!A%7)ߙ5jy ,$Ha/ykDZP"ȬG&6\B~i!f%"O$ \9+32,㋪" y*"<0rQU]l2^xB,8+4 3Z6Lf#Vqxs"˗>W8;Q6X&X9*xA1T|8 L+. AmOG0wŖvH4u^ELx!X}ȨumLjFx-`!B#k ;,$_bѿp4Ւ¦$(ʿ&NUVm_aغL%士04#({vX1"X\Ū;{J{+%qhXq;I|Lr""͡{lJ#\'hZ \ܿӝEջ#&wzyfĈX{!X%)2Nu~ׁqErj; ,#t,v76WԚLAr"¬87{z#L7x@~V S摋J䠃# ll]炇,Voi蔈ow^w,kLj蕃#*c+rVa#ɚNm)WLۖ֌o"q5 5TKG8`b׭c-&ptJJ4:_b.F뿞QCFc~5~Fa0X _DpC$OB!/#B O9$@+-A؇=;eigenbase-farrago-0.9.0/doc/design/CollectionTypes.html0000444000175000017500000003415411173714170023010 0ustar drazzibdrazzib SQL Standard Collection Types

SQL Standard Collection Types

This document describes standard support for collection types in SQL99 and SQL2003. The specifications are informal; for details, see the relevant portions of the standards. None of this is implemented in Farrago yet.

SQL99 Array Type

SQL99 introduces limited support for a single collection type known as arrays. Arrays are variable-sized ordered collections with a declared maximum cardinality. Here's an example of how to declare a column with array type:

CREATE TABLE genome_sequences(
    sequence_id BIGINT NOT NULL PRIMARY KEY,
    chromosome_number INT NOT NULL,
    start_offset BIGINT NOT NULL,
    codons CHAR(3) ARRAY[1000] NOT NULL);
Elements of the array may be declared with almost any datatype (in this example, CHAR(3)). However, in SQL99, nested arrays are illegal (whether the nesting is direct or indirect); you can't declare

    illegal_column1 INT ARRAY[3] ARRAY[5]
nor can you declare

    illegal_column2 ROW(INT,DOUBLE ARRAY[7]) ARRAY[4]
(This restriction is removed by SQL2003.)

Array values are created with the ARRAY constructor:


INSERT INTO genome_sequences VALUES(
    10032423, 3, 432432, 
    ARRAY['CUG', 'AAG', 'GGU', 'ACU', 'CUU', 'GGU', 'UGG', 'UAA']);
The length of an array is retrieved with the CARDINALITY function:

SELECT sequence_id,CARDINALITY(codons) as sequence_length
FROM genome_sequences
ORDER BY sequence_length;
And the actual values can be selected with the usual bracket syntax:

SELECT 
    sequence_id,
    codons[1] as first_codon,
    codons[CARDINALITY(codons)] as last_codon
FROM genome_sequences
ORDER BY sequence_id;
Notice that array offsets are 1-based. Attempting to read an out-of-bound offset (or to write an offset past the maximum cardinality) results in an exception. Any element of an array may be null, and there is no straightforward means of declaring them NOT NULL. Updating an element past the current cardinality automatically extends the array and sets any new elements thus created to null.

Arrays can be concatenated with the usual notation:


CREATE VIEW spliced_sequences AS
SELECT s1.sequence_id, s1.codons || s2.codons AS spliced_codons
FROM genome_sequences s1, genome_sequences s2
WHERE s1.chromosome_number = s2.chromosome_number
AND s2.start_offset = s1.start_offset + CARDINALITY(s1.codons);
Array elements can be set individually in the SET clause of an UPDATE statement, or the entire array can be set as the target of an INSERT or UPDATE:

UPDATE genome_sequences
SET codons = 
    (SELECT codons 
     FROM spliced_sequences 
     WHERE spliced_sequences.sequence_id = genome_sequences.sequence_id);
Array assignment in which the maximum size of the target is less than the actual size of a source value results in an exception. In the example above, this will occur if two sequences spliced together make up a sequence longer than 1000 codons.

Arrays can be compared for exact match with = or <>:


CREATE VIEW matching_sequences AS
SELECT s1.sequence_id as sid1, s2.sequence_id as sid2
FROM genome_sequences s1, genome_sequences s2
WHERE s1.codons = s2.codons;
No other inequality operator is supported, and usage of arrays in just about any other context (including GROUP BY) is illegal. The UNNEST operator converts an array into a query expression:

-- convert a particular sequence into a table
SELECT codon,offset
FROM UNNEST((SELECT codons FROM genome_sequences WHERE sequence_id = 10032423))
     WITH ORDINALITY 
     AS codon_table(codon,offset)
ORDER BY offset
The WITH ORDINALITY clause specifies that the array ordering should be used to derive the offset column. Without this clause, the codons would be returned without any ordering information. What if we wanted to convert all of the sequences together? That's what the new LATERAL derived table feature is for:

SELECT 
    g.sequence_id,
    codon_table.codon,
    codon_table.offset as relative_offset,
    g.start_offset + codon_table.offset - 1 as absolute_offset
FROM 
    genome_sequences g,
    LATERAL(UNNEST(g.codons) WITH ORDINALITY)
    AS codon_table(codon,offset)
WHERE chromosome_number = 7
ORDER BY absolute_offset,sequence_id
This should result in a table containing all of the codons from chromosome #7. The first column is the sequence containing the codon. The second column is the codon itself. The third column is the relative offset of the codon within the sequence. The last column is the absolute offset of the codon within the chromosome. Returned rows are ordered by absolute position.

Note that the new LATERAL keyword is normally required in order to reference a table expression defined earlier in the FROM list (g in this example). However, when UNNEST is specified, LATERAL is implicit.

SQL2003 Array Type

SQL2003 extends array semantics in a number of ways. Arrays can be declared without a maximum cardinality, in which case the maximum is vendor-defined (possibly unbounded like a LOB). Array nesting is unrestricted. And a new constructor is added for converting a query into an array:

INSERT INTO listbox_choices VALUES(
    'Department Names',ARRAY(SELECT name FROM sales.depts ORDER BY 1));

SQL2003 Multiset Type

SQL2003 also introduces another collection type known as a multiset. A multiset is much like an array, but unordered, and has more useful operators. Although multisets and arrays are both collections, they don't mix (e.g. you can't INSERT a multiset into an array column).

Unlike arrays, multisets never have a declared maximum cardinality:


CREATE TABLE logins(
    session_id INT NOT NULL PRIMARY KEY,
    successful BOOLEAN NOT NULL,
    uid INT,
    attempts ROW(VARCHAR(128),VARCHAR(128)) MULTISET);
Multiset constructors are similar to array constructors:


INSERT INTO logins VALUES(
    1000,true,0,
    MULTISET(
        ROW('root','31337'), 
        ROW('scott','tiger'), 
        ROW('root','beer')));

INSERT INTO logins VALUES(
    1001,false,0,MULTISET(SELECT ROW(name,password) FROM bogus_accounts));

(Note that ORDER BY is not allowed on a multiset constructor query since multisets are unordered.) As syntactic sugar, another constructor named TABLE is also provided which automatically converts a query into a multiset of rows. The next example is equivalent to the previous query-based MULTISET constructor:

INSERT INTO logins VALUES(
    1001,false,0,TABLE(SELECT name,password FROM bogus_accounts));

CARDINALITY returns the total number of elements in a multiset (not the number of distinct elements). Multisets cannot be concatenated (since they aren't ordered); instead, a number of set operators are provided for multisets:



multiset1 MULTISET UNION [ALL|DISTINCT] multiset2

multiset1 MULTISET INTERSECT [ALL|DISTINCT] multiset2

multiset1 MULTISET EXCEPT [ALL|DISTINCT] multiset2

Some multiset-specific predicates are also provided:


-- find sessions with a particular username/password combination
SELECT session_id
FROM logins
WHERE ROW('root','31337') MEMBER OF attempts;

-- find sessions where no combination was retried
SELECT session_id
FROM logins
WHERE attempts IS A SET;

-- find sessions whose attempted combinations subsume those of other sessions
SELECT a.session_id as sub_id,b.session_id as super_id
FROM logins a,logins b
WHERE a.attempts SUBMULTISET OF b.attempts;

UNNEST can be used on a multiset (but not WITH ORDINALITY, obviously). The multiset-specific ELEMENT operator converts a multiset with cardinality 1 into a row expression:

SELECT session_id,ELEMENT(attempts).name
FROM logins
WHERE CARDINALITY(attempts) = 1;
Finally, aggregation operators are provided for collecting row values into multisets, and for aggregating multisets:

SELECT 
    uid,
    COLLECT(session_id) AS session_ids,
    FUSION(attempts) AS all_attempts,
    INTERSECTION(attempts) AS common_attempts
FROM logins
WHERE successful
GROUP BY uid;
For each user, the query above returns a row with the uid key and three multiset columns. The session_ids column contains a multiset of the sessions which successfully logged in that uid. The all_attempts column contains a multiset of all of the username/password combinations used for that uid. The common_attempts column contains a multiset of any username/password combinations which were tried for all logins of that uid.

Implementation

Many existing system components will be involved in the implementation of collection types. It might be possible to use a rewrite approach to keep collection types out of the optimizer and executor via hidden joins and locators, but this would make it very difficult to preserve good locality of reference for small-to-medium sized collections.

Instead, a more straightforward approach is to treat collections as opaque variable-length byte arrays in parts of the system which don't need to understand them. This implies that collection size will be bounded by implementation details such as page size. (Eventually, once Farrago has LOB support, it should be used to remove size limits on collections.)

A natural internal structure for these byte arrays is the same format we use for passing tuple data between XO's: a contiguous sequence of marshalled tuples. (For collections of non-row type, these would be 1-tuples; for collections of row type, we need an indicator for the entire row being null--maybe a hidden boolean attribute.) A fixed-size header containing information such as cardinality might also be necessary.

Given this representation, it's also natural to implement collection operations via standard XO's. For example, multiset UNION can be implemented in the same way as a normal query UNION. The collection byte array can be referenced directly as input to these XO's. To accomplish this, several components must collaborate:

  1. The optimizer must identify subtrees of row expressions where all the nodes are collection operations, transform these into corresponding relational expressions, and generate a subplan implementation for them. The ExecutionStreamDefs thus generated will be disconnected from the rest of the query tree. (Note that the optimizer already supports disconnected graphs, and the process of identifying collection expression subtrees is similar to some of the existing FarragoAutoCalcRule code.)
  2. A new calculator instruction is required for invoking a subplan. The instruction is responsible for accessing the byte-array registers corresponding to collection-valued inputs, binding them to the input XO's in the subplan, executing the subplan, and then copying the subplan's output into a byte-array result register. (Alternatively, a specialized XO could be used instead of the calculator.)
  3. The optimizer must work together with the calculator code generator to bind the subplan to the generated instruction.
In fact, much of this is similar to what's needed in order to execute correlated subqueries when they are not rewritten as joins, so this work is useful for more than just collection type implementation.

Based on the above approach, here are the components affected and estimates for the amount of work needed to implement multisets (but not arrays, which can be tackled as a follow-on project):

  • Parser (including SqlNode/SqlOperator representation). [4 days] This covers:
    • multiset constructor from values
    • multiset constructor from query
    • multiset table constructor from query
    • multiset UNION/INTERSECT/EXCEPT
    • ELEMENT operator
    • MEMBER OF operator
    • IS A SET operator
    • SUBMULTISET OF operator
    • COLLECT operator
    • FUSION operator
    • INTERSECTION operator
    • UNNEST/LATERAL operator
    • CARDINALITY function
    • multiset type declaration in DDL parser
  • Validator: validation for operators, functions, and DDL (see parser list). [5 days]
  • Sql2RelConverter: convert LATERAL query WHERE clause to extra join condition, UNNEST to UnnestRel, and various other operators (see parser list). Initial implementation will be very restrictive in terms of what is supported inside of a LATERAL query. [4 days]
  • Type system: add collection types. [2 days]
  • Optimizer: UnnestRel representation; generate subplans for multiset operators. [7 days]
  • Executor: XO's for converting from TupleStream to single multiset value and vice versa. REVIEW: anything special needed in aggregate XO's for implementing COLLECT/FUSION/INTERSECTION? [3 days]
  • Calculator: new instruction for executing subplan (includes code generation work). [6 days]
  • JDBC driver: java.sql.Array implementation (have to use this for multisets since nothing else exists). This requires extra support for executing a special kind of subplan to produce the ResultSet representation of the collection. This feature is optional (UNNEST is much more powerful and can be used to accomplish most of the same functionaliy.) [8 days]

Notes

eigenbase-farrago-0.9.0/doc/design/UserDefinedTypesAndRoutines.html0000444000175000017500000005002411173714170025260 0ustar drazzibdrazzib SQL Standard User Defined Types and Routines

SQL Standard User Defined Types and Routines

This document describes standard support for user-defined types and routines in SQL:2003. The specifications are informal; for details, see the relevant portions of the standard. Much but not all of this is already implemented in Farrago.

User-Defined Types

In SQL:2003, it's possible to extend the type system in a number of ways:
  • The traditional concept of a domain is preserved from SQL92. A domain is not actually a user-defined type; it's really just an alias for a combination of a builtin type with a default value and a set of constraints. A column based on a domain can be assigned and compared with values of the underlying builtin type directly; there's no need (or even mechanism) to convert between the domain and the builtin type. Domains cannot be used to declare anything but columns; e.g. you can't declare a parameter to an SQL routine as a domain.
  • The simplest kind of user-defined type is a distinct type. Like a domain, a distinct type is defined in terms of a single builtin type. Unlike a domain, a distinct type is not directly assignable or comparable with the underlying builtin type or other distinct types based on it. Instead, explicit conversions are required. The canonical example for why distinct types are a good idea is the Mars Climate Orbiter, which crashed due to an error from mixing imperial and metric units without conversion. Here's a simple example of distinct type definition:
    
    CREATE TYPE metric_meter AS DOUBLE;
    CREATE TYPE imperial_foot AS DOUBLE;
    
  • More generally, a structured type is defined much like a class in an object-oriented programming language such as C++ or Java. A structured type is defined with an arbitrary number of attributes of any type (including user-defined types), and may optionally inherit from another structured type (single-inheritance only). Types may be FINAL or NOT FINAL (as with the Java final modifier) and INSTANTIABLE or NOT INSTANTIABLE (as with the Java abstract modifier). Here's the classic OO example:
    
    
    CREATE TYPE Shape2D
    NOT INSTANTIABLE
    NOT FINAL;
    
    CREATE TYPE Circle UNDER Shape2D
    AS(
        radius DOUBLE DEFAULT 1
    )
    INSTANTIABLE
    FINAL;
    
    CREATE TYPE Rectangle UNDER Shape2D
    NOT INSTANTIABLE
    NOT FINAL;
    
    CREATE TYPE Square UNDER Rectangle
    AS(
        side_length DOUBLE DEFAULT 1
    )
    INSTANTIABLE
    FINAL;
    
    CREATE TYPE Oblong UNDER Rectangle
    AS(
        width DOUBLE DEFAULT 1,
        length DOUBLE DEFAULT 2
    )
    INSTANTIABLE
    NOT FINAL;
    
    Attributes can have default values, but not constraints (meaning you can't even declare an attribute as NOT NULL). It's not even possible to use domains to work around this, since domains can only be based on builtin types. However, it is possible to use column-level constraints or validation code in a constructor instead.
    
    
    CREATE TABLE PolkaDots(
        dot_id INT NOT NULL PRIMARY KEY,
        Circle dot NOT NULL CHECK ((dot.radius > 0) IS TRUE),
        center_x DOUBLE NOT NULL,
        center_y DOUBLE NOT NULL);
    
    Note that the NOT NULL constraint on dot applies to the Circle object as a whole (not to its radius attribute, which is validated by the CHECK clause). Attempting to reference an attribute of a null type instance results in NULL (not an exception as you might expect).
  • Finally, an entire Java class can be used as the implementation of a user-defined type, as specified in SQL/JRT, also known as SQLJ Part 2. Java user-defined types differ significantly from non-Java structured types, so they aren't currently covered by this document.

Typed Tables

SQL:2003 allows structured types to be used in two different modes:
  • In the same fashion as a builtin type. For example, one might replace the three columns first_name/middle_name/last_name in a table with a single column of structured type full_name, and similarly for the parameters of user-defined routines which operate on names.
  • As the underlying definition of a typed table. A typed table is similar to the concept of an extent in an object-oriented database; it provides persistence and object identity for values of a user-defined type, and automatically maps the attributes of the structured-type onto the columns of the typed table. It also maps type inheritance onto extent inheritance (allowing, for example, a query against a shape table to implicitly union all circles with rectangles).
This document does not cover typed tables any further, nor does it cover locators and references; instead, the focus is on the semantics of structured types and their instances.

Routines

SQL behavior can be extended by defining various kinds of SQL-invoked routines. SQL-invoked routines may be implemented in the SQL standard stored procedure language, SQL/PSM (in which case they are called SQL routines), or in another language such as Java (in which case they are called external routines, defined in SQL/OLB, also known as SQLJ Part 1). The choice of implementation language is orthogonal to the contexts in which routines may be invoked, as listed here:
  • Procedures are routines invoked explicitly via the SQL CALL statement. Procedures are not associated with a particular type, and cannot be used in SQL row expressions. An SQL-invoked procedure is similar to a C++ free function with void return type.
    
    CREATE PROCEDURE raise_annual_salary(IN raise_percentage DOUBLE)
    LANGUAGE SQL
    MODIFIES SQL DATA
    BEGIN
        UPDATE emps SET salary = salary + salary*raise_percentage;
    END;
    
    CALL raise_annual_salary(0.10);
    
    
  • Functions are routines which are invoked from SQL row expressions. Functions are not associated with a particular type. An SQL-invoked function is similar to a C++ free function with non-void return type.
    
    CREATE FUNCTION sqr(x DOUBLE) 
    RETURNS DOUBLE
    LANGUAGE SQL
    CONTAINS SQL
    RETURN(x*x);
    
    SELECT sum(3.1415927*sqr(d.dot.radius)) as total_area FROM PolkaDots d;
    
    
  • Methods are routines which can be invoked from SQL row expressions and which are associated with a particular type. An SQL-invoked method is similar to a method in C++ or Java, and may be either static (type-level) or non-static (instance-level). Methods are declared as part of the type definition, but defined separately. Methods are normally invoked with a parenthesized argument list, but for niladic methods the parentheses can be dropped:
    
    CREATE TYPE Shape2D
    NOT INSTANTIABLE
    NOT FINAL
    INSTANCE METHOD area() RETURNS DOUBLE CONTAINS SQL;
    
    CREATE TYPE Circle UNDER Shape2D
    AS(
        radius DOUBLE DEFAULT 1
    )
    INSTANTIABLE
    FINAL
    OVERRIDING INSTANCE METHOD area() RETURNS DOUBLE CONTAINS SQL;
    
    CREATE TYPE Rectangle UNDER Shape2D
    NOT INSTANTIABLE
    NOT FINAL
    OVERRIDING INSTANCE METHOD area() RETURNS DOUBLE CONTAINS SQL
    INSTANCE METHOD rect_width() RETURNS DOUBLE CONTAINS SQL
    INSTANCE METHOD rect_length() RETURNS DOUBLE CONTAINS SQL;
    
    CREATE TYPE Square UNDER Rectangle
    AS(
        side_length DOUBLE DEFAULT 1
    )
    INSTANTIABLE
    FINAL
    OVERRIDING INSTANCE METHOD rect_width() RETURNS DOUBLE CONTAINS SQL;
    OVERRIDING INSTANCE METHOD rect_length() RETURNS DOUBLE CONTAINS SQL;
    
    CREATE TYPE Oblong UNDER Rectangle
    AS(
        width DOUBLE DEFAULT 1,
        length DOUBLE DEFAULT 2
    )
    INSTANTIABLE
    NOT FINAL
    OVERRIDING INSTANCE METHOD rect_width() RETURNS DOUBLE CONTAINS SQL
    OVERRIDING INSTANCE METHOD rect_length() RETURNS DOUBLE CONTAINS SQL;
    
    CREATE INSTANCE METHOD area()
    RETURNS DOUBLE
    FOR Circle
    RETURN 3.1415927*sqr(radius);
    
    CREATE INSTANCE METHOD area()
    RETURNS DOUBLE
    FOR Rectangle
    RETURN rect_width*rect_length;
    
    CREATE INSTANCE METHOD rect_width()
    RETURNS DOUBLE
    FOR Oblong
    RETURN width;
    
    CREATE INSTANCE METHOD rect_length()
    RETURNS DOUBLE
    FOR Oblong
    RETURN length;
    
    CREATE INSTANCE METHOD rect_width()
    RETURNS DOUBLE
    FOR Square
    RETURN side_length;
    
    CREATE INSTANCE METHOD rect_length()
    RETURNS DOUBLE
    FOR Square
    RETURN side_length;
    
    SELECT d.dot.area FROM PolkaDots d;
    
    SELECT d.dot.area() FROM PolkaDots d;
    
  • Constructor functions are special niladic functions which create new instances of types. By default, the system defines a constructor function for each type which sets all attributes to the default value; this definition cannot be overridden. Constructor functions may not be invoked except via the NEW expression:
    
    INSERT INTO PolkaDots VALUES(1,NEW CIRCLE(),0,0);
    
  • Constructor methods are special methods which initialize a new instance of a type. Constructor methods are also invoked via the NEW expression, which (when given arguments) combines the system-defined constructor function with the appropriate user-defined constructor method:
    
    CREATE TYPE Circle UNDER Shape2D
    AS(
        radius DOUBLE DEFAULT 1
    )
    INSTANTIABLE
    FINAL
    CONSTRUCTOR METHOD Circle(radius DOUBLE) RETURNS Circle 
    SELF AS RESULT
    CONTAINS SQL;
    
    CREATE CONSTRUCTOR METHOD Circle(radius DOUBLE)
    FOR Circle
    RETURNS Circle
    BEGIN
        SET SELF.radius = radius;
        RETURN SELF;
    END;
    
    INSERT INTO PolkaDots VALUES(2,NEW CIRCLE(20.5),10,100);
    
    (Note that the SQL SELF keyword serves the same purpose as the this keyword in Java.)
  • Observers are special niladic methods which read an attribute of a type (where the name of the attribute is the same as the name of the observer method). The system defines observers for all attributes automatically, and they cannot be overridden.
    
    SELECT d.dot.radius() FROM PolkaDots d;
    
    SELECT d.dot.radius FROM PolkaDots d;
    
  • Mutators are special monadic methods which instantiate a copy of an existing structured type instance and modify one of the copy's attributes (where the name of the attribute is the same as the name of the mutator method). As for observers, the system defines mutators for all attributes automatically, and they cannot be overridden. Mutator semantics are certainly confusing. The example below returns a result set of Circle objects equivalent to the dots in the PolkaDots table with doubled radii. Despite appearances, it does not directly return the radii themselves:
    
    SELECT d.dot.radius(d.dot.radius*2) FROM PolkaDots d;
    
    Traditional attribute lvalue semantics are also supported for updates:
    
    UPDATE PolkaDots SET dot.radius = dot.radius*2;
    
    This is equivalent to:
    
    UPDATE PolkaDots SET dot = dot.radius(dot.radius*2);
    

Routine Modifiers

A number of modifiers can be applied to routines when they are defined:
  • LANGUAGE: this specifies the implementation language. The examples above all used SQL, but later we'll see some examples which specify JAVA instead.
  • PARAMETER STYLE: this can be one of {SQL | GENERAL | JAVA} and controls how routine parameter lists are mapped into other languages for external routines.
  • SPECIFIC name: an additional name by which an overloaded routine is known in the catalog. This allows a routine to be referenced by specific name without having to include its full signature.
  • [NOT] DETERMINISTIC: specifies whether the routine always produces the same result given the same inputs and persistent state.
  • [NOT] DYNAMIC_FUNCTION: specifies whether it is safe to cache query plans referring to the routine; default is false (NOT DYNAMIC_FUNCTION), indicating that plan caching is safe. An example of a DYNAMIC_FUNCTION would be an external value lookup routine (similar to the CURRENT_DATE expression) which should be re-evaluated for each query execution, but not for each row. Note that this is a Farrago-specific extension (not defined by SQL:2003).
  • {NO SQL | CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA }: constrains the usage of SQL within the implementation of the routine.
  • DYNAMIC RESULT SETS: for procedures, whether result sets are returned when the procedure is invoked. Procedural result sets are not covered in this document.
  • [ RETURNS NULL | CALLED ] ON NULL INPUT: for functions, whether the routine is actually called if one of its arguments is NULL. RETURNS NULL forces the executor to short-circuit the function invocation, supplying NULL for its result.

Routine Parameters

Most routine parameters are input-only. However, procedures allow parameters to be specified as one of { IN | OUT | INOUT }. Parameter names are optional (but still recommended) when an external routine is specified, since external routine lookup is by type signature. Parameters do not take default values.

Casting Around a Type Hierarchy

The equivalent of the Java instanceof keyword is the IS [NOT] OF syntax:

SELECT p.name
FROM ParkingLots p
WHERE p.geometry IS OF (Square,Circle);
Casting is sometimes required to get the right version of a method due to overloading or overriding. The normal SQL CAST keyword is not used for this purpose. Instead, the syntax for downcasting uses the TREAT keyword:

SELECT TREAT(p.geometry AS Square).side_length
FROM ParkingLots p
WHERE p.geometry IS OF (Square);
For upcasting, the TREAT keyword is omitted:

SELECT generate_label(d.dot AS Shape)
FROM PolkaDots p;
If the generate_label function were overloaded with different versions for Circles and for generic Shapes, then the query above will invoke the generic Shape version. For the gory details on routine resolution, consult the standard.

Besides explicit type hierarchy casting, SQL:2003 also provides for

  • User-defined casts via the CREATE CAST statement. These are relevant for structured types; for distinct types, cast functions to and from builtin types can be referenced as part of the type definition.
  • User-defined comparisons via the CREATE ORDERING statement.
  • User-defined transformation to and from representations which can be used in non-SQL programming languages. These are defined via the CREATE TRANSFORM statement, which is unnecessary for Java; JDBC already defines the SQLData interface for this purpose.
  • Implicit casting on the return value of functions via the CAST FROM clause (mostly useful with external routines where the routine wasn't defined with SQL in mind).
  • Type-preserving functions via the RESULT clause; I haven't decoded this part of the standard yet.

Bookkeeping

After a type has been defined, it can be maintained with the ALTER TYPE statement, which allows for
  • add attribute
  • add method
  • drop attribute
  • drop method
Types can be dropped, but only with RESTRICT semantics (no CASCADE).

Procedures, functions, and types may be defined in any schema, but methods must be defined in the same schema as the associated type.

SQL:2003 introduces the notion of a SQL-path, which is used to resolve unqualified references to procedures, functions, and types (similar to the way the PATH environment variable is used to resolve executable names). Each schema has a SQL-path associated with it; objects defined within that schema use that path implicitly. Sessions also have their own SQL-paths used for dynamic SQL.

As with table references in views, unqualified routine references are "frozen" at the time the invoking code is validated so that subsequent path changes do not affect them. However, the situation is a little more complicated in the case of late binding; instead of freezing on a single routine, the system freezes a candidate set with final matching performed at execution time. In the examples above, an invocation of shape.area() does not know until execution whether a particular shape is a Rectangle or a Circle.

External Routines

So far all of the examples have defined SQL routines (using SQL/PSM for the procedure implementation language). For Farrago, we are also interested in using Java as a routine implementation language. SQL/OLB provides this, including the capability to embed SQL in Java. However, it does NOT allow methods to be defined in Java for normal structured types, only procedures and functions. In order to define methods in Java, you have to go all the way and use Java structured types (SQL/JRT, not covered here).

Defining a routine with a Java implementation is a multi-step process:

  1. Write the routine and compile it as a Java class (possibly using a SQLJ precompiler to translate any embedded SQL statements).
    
    class MathFuncs {
        public static double sqr(double d)
        {
            return d*d;
        }
    }
    
  2. Package the compiled Java class into a JAR file.
  3. From SQL, CALL the system-defined SQLJ.INSTALL_JAR routine to install the JAR into the DBMS. (The last parameter, which controls whether deployment descriptors are used, is currently ignored since these aren't supported yet.)
    
    CALL SQLJ.INSTALL_JAR('file:/home/jvs/MathFuncs.jar','MathFuncsJavaLib', 0);
    
  4. Issue a CREATE {FUNCTION|PROCEDURE} statement referencing the routine's Java implementation in the installed JAR.
    
    CREATE FUNCTION sqr(d DOUBLE)
    RETURNS DOUBLE
    NO SQL
    EXTERNAL NAME 'MathFuncsLib:MathFuncs.sqr'
    LANGUAGE JAVA
    PARAMETER STYLE JAVA;
    
Unfortunately, there's no way to combine all of this into a single DDL statement with the routine body inline. We may want to consider an extension for this, e.g.

CREATE FUNCTION sqr(d DOUBLE)
RETURNS DOUBLE
NO SQL
INLINE
LANGUAGE JAVA
PARAMETER STYLE JAVA
    {
        return d*d;
    }
;
The schema named SQLJ is a special schema maintained by the system (just like INFORMATION_SCHEMA). It contains other procedures for JAR maintenance (REPLACE_JAR, REMOVE_JAR, ALTER_JAVA_PATH). Besides Java classes, JAR files can also contain deployment descriptors such as the DDL for creating the SQL routines and granting access to them. In a way this is the inverse of the inline routine definition mentioned above: instead of defining everything in SQL, define everything in the JAR, and then issue a single CALL from SQL to deploy it.

Access Control

SQL:2003 types have no concept of access control such as the public/private/protected of Java and C++. However, the standard (and more powerful) GRANT/REVOKE mechanism can be used at the method level instead.

When external routines execute SQL statements, the authorization with which they run can be controlled via the EXTERNAL SECURITY clause on the routine definition:

  • EXTERNAL SECURITY DEFINER: the routine executes with the privileges of the user who created the routine.
  • EXTERNAL SECURITY INVOKER: the routine executes with the privileges of the user who invoked the routine.
  • EXTERNAL SECURITY IMPLEMENTATION DEFINED: the system decides (may be any user at all!).
SQL routines always run with INVOKER privileges.

User Defined Aggregates

SQL:2003 does not provide a mechanism for user-defined aggregates. See the Oracle, DB2, and PostgreSQL docs for various vendor-defined extensions in this area.
eigenbase-farrago-0.9.0/doc/design/medjdbc.html0000444000175000017500000000047711173714170021261 0ustar drazzibdrazzib Farrago SQL/MED Plugin for JDBC

Farrago SQL/MED Plugin for JDBC

This page has been relocated to the Farrago wiki. eigenbase-farrago-0.9.0/doc/design/OptimizedTree.gif0000444000175000017500000006216311173714170022256 0ustar drazzibdrazzibGIF89a  $$$(((,,,000444888<<<@@@DDDHHHLLLPPPUUUYYY]]]aaaeeeiiimmmqqquuuyyy}}},yH*\ȰC#>HHŋ3jȱǏ CIɓ(S×0cʜI͛8sɳϟ@ Jԧ *]ʴӧPJJիXjʵׯ`ZٳhӪ]˶۷p-hËx˷߿ LÈ+^̸-@x0˘3k̹纏CMӨS9 ʞc˞M۸]ͻ Ë׹+_μ}Ͽ(x~% W^(VhK66^^($_}"|&(4v"8#j.X@)dQ7hH֣C6P.TdTViLF\8`#Yvih Ap)tix|矀*蠄梌6ڜ 4 餔Vj饘f馜v駠*ꨤjꩨj *묛˜;ٮ̾Dlжl`Fk>BM܆+ڎkMU;cP~+o Do_+K 7\^ GlŖA1C "Gq^<̲'4r <>/qmt7)+tI?&Ek 88tu]]`[u]R= @!$@$ v w|M xfFYӝ7Pv+ < <؝P0 zwVo t<@܋pSֶ 'z@O>iwzn;tpJl g t%x.0+TB8.-~ofwH:qrx/% `Q"M$@@*!9/s|H@a@ B׿P@y Qa!5HBPoA9o.X`e @KA6dgq)(+jq<@:W,J· : @&gBIeD(F.x\uPrׁuk*T_FNDl(3fn ^pGGѱ(K6-z 0~<'s~-Y- ' Bn"Ic[ b>B򘄀7 $ 4̓Gk_* zP Iʅs e-v 9Z.  XNx; םj sWJ5X@yAYտjm)ByADB12#y@ǯ y>,S@V!=1{|(הMo!K_Fၻ P@Ͽ'pX. x'0 'U D`|Ko+لJd 6dEmE)+P3^JiイQ@J Qz5Qi9uCB#F5I %|MCJG5[th%WJEMd0bE6 @Ow7VԇQeQ5h#uDQH[rB~7~.4m!mgoiS$N' O EPhYs}и@)*M؉I(ar0#9"U!t`$Fu<6T6IChwQ#-x_lzF6,Q{%DS<`FfQB= Fci9q3ʓ0@F;{Y'4D1*&}._(mh? 6:Ǧmc6ISsCwBb:4@%;*7dDE.@G?y8' :E4XINq:8WdB wyZj d[ eij7zuRyayGz&(!uq+r /Yx:C9G@&Gȓ8:>_r{ۢMP:K[:WW0+Eˇ %X_@;uKhyY˗7XNu_W Kl /ϊ6ocLz_oc91;3 '5HYz:7HS=~s;)늴zG_ {#:;9yj*65Ǣՙع|XR;[Xt;@yУE۬Zrى0(VtB 0!ao/BhtJ1;3sqV#i"]'1%K-<16 !&uζ^B$Ll{k"B 5b4ҫo˘Rp0qN2$lhdgFc2z$(`C2T\L 6Nb'Y)y^|q14pP"%H'#*U:#5R&; [о;]҂x .QB$h:uT'Ac+ QBy9&}i1*#6+лV 65mg119M#K˸f(ӃSF] 1%dCU=%ҽ&,L+D]c]sg"bol,ߜ+d,f4b@.tm!^<ǀl4 =-=!xwxɌ ׎+""L3:,M C"W,2=$&7 {=2$ܕ\@/ɌL"}10xއGe5}ކwAܔ-.N-v* ~ !m|j}-2* --Ѩ9%3]u"~90 b'v.#1 ?,\9pY16=/!Y-"\ !R0&uB5!16 |.*.Y6';u#-!ˎ>rW Vw6 e"f$: ~ꨞ =0&7#붾(`L \&"gb4Bb/Qܢz,#^%0.!1pBea v]EBab+&BBa؂ɮ $"AAblͥ"@!B /6^, o2^eo'_!5? +--"$/&r=q. b<̢ M?LA;aBnz+":A0c%9!Ƃi.|?~_,Az+_Z< 8>89fBgc2h%\?:P01IkSr64N-Q'LCJ8X|CGMNL6 )@bUOب _@t_kK{1!C@ D8 >QD-^ĘQF. pRH=DReI.VGC!GVN\!39 h4+-B '*0C>B >t"L@@T\9n);*OŪxrmě~ansQȺf2@p@GJ2o>Fڍ)1#+̸:`oIs35O?_?BD|jцF| ƗdTF;x`C39z:rT?sҲ(ԲOU uK2T8A5:jԁش7 6a!A6[m!s[oK2$hkTN'mTJ G:\5EjT2ݔ#S 0VtNDQtS5"];CT 3CX{HAL lZкedeCPqN KT뢠#2h]r (Ò%7vjQt%LSrq4ȬFQ5K=v&9^,=NGڏ>SHRMWnΠ*%I Ȇ/u{G(gZ3)~rGi/u'`y-~|Հ"8'FJ ă>XP+: x`|d BXO%Ķ/>E82J@.!"!]I k8p%~_hQf dpGLrж[=op2{ƍ5:YAɄNPc:ڕtT+g(G.W9A#Ej(!$yT.h $S4P~nz%P^YdeFf6 etH!iGQ"XDASѱ.ߵk^&  Iܥdw2K!Fs[дg>gO}j ]z7|5euzH]$shRڄ-D;_O!Rbk%?9 c9z&y<8! q@"I/uEeђhe}GRjMjt#f H!H#ff ,ml*!IU?)5!LWi}U Xf_5X RKwA VAD|*Xi?M ?>>!=8eAɻثKo(@gF| Dʛΰ%+1%ˬ!d*k[{BC+D XBsU|VW;Z#c+ċEOlz?)őF1GZFہRudvtwxyzG|}~GvP Р#CcFLjD7|ȍȎȏɐɑ$ɒ4IdPIPI`ɘəɚlX AK>g 8ǮHxtʧʨʩʪʫʬ ^ʯ˰˱$ȿ ?1Éڻd3?@A%B5CEDUETFӢFIJK=TH  PQ%R5SETUUeVuWXY}:RS0L_`cEdUVPchijkV4J֤\] q%r}`n=N WfWty% ueWz~s'\׫VU؅e؆u؇؈؊؋؇%؎؇׏咁ʂ5DٔUٕezX٘ ٘!JٜٝEYWmן%ڢP5ZڒڤuڧAڊXڛmکڬQZ̨Zٮ۱=7%[̴Yڳe۶+u[M۩ ۸ۻE-ۯ۵ۿ\1[[EčUȕa\u\um}%]{uuJEu]\Uݦd׵ۍ+Uڹ5\ވݳ[ Eފ^-M^Xޱm^ߍ^ޮ% _U_=߬M_m_}_םߩ_`_{L3 VѡAXX+ 7X*ǒǵ&ᤕ'Z@"䬄KL.`aHa=xC@n".\!)u  XT<"((H㡈 2 0 xc/f9 E:B5|c_ٜj! Z86.M4JŐa* b pM;`yPc)!3b#OfWzL"a+G jۭA"dMLKeV!S `Jf=)+: Ra=ّn>b)Pg KznofްC=sd 1kf bpހY:@ 3&>'>B"<&ApXidHQ>糑(nZgn#yTyݘ:g l4';l1a).؟:hU#ZܤF{ i,) ,Ꙉ)+<.PtJ85yJJO`$OZ%g(9'7Z(+r,r&.sr 1G*=4wsZsm7rݝ:=ts@7t{-Cgt3Jt]Fs܍Itڪ۽LyO't-^Rgu} uphZwWYՕuZ^#\Xu_'0va/ecXUvf:-hljw]vmwoqosKnoݪ5wtww?w]vzϐxנw{ w{}]u' 0|RW' HYe?T Gy?uwypWrye݀xWo8`'z gX/grKwz zӬ{'{uӲG{=g]UӸ{{EG޿?^7]W:w_Ѕ7Z'[Z `}}7}-W} XګOZ٧z/T X'W w~ ` dGWgwOPoO9 ,h „ 2l!ĈB`ƌ7r#Ȑ"G,i$ʔ*Wl%̘2ghA:w'РBn`@J2miSH\i*֬Zr+X7sB-k,ڴݠ-ܸrJ}A5,޼zoޱs.lx`Znqںvl2̚7 3 4' 5زgvY5܎MP7’m8yYЧSg:8ڷscǓ/o>*ſoӯoL7 Y~ :ȑJ8!.j!Eh!!8bAf!)ه$"x5xW1`=#A 9$Ey$I*$M:$QJ9%UZy%Yjy4%a@ y&i&m&q9'uy'y'}' :( zb*(ABJ:^0~j醏r)d)z*{*P:kfz+*P+W;,P*lJ2,PZ{j^"T-[{.F2; 5lU:ɥc=# `2Fcpx%$oɫz $8@A4וc9ajޮc;'prbߞpowzyU H$L>3jp@}!X 7oxJ+>@v@y<(߼G=ohӚ&h|jY>;]dN .oŸv;M>|A< ZeAC6)3 wxPj3b1CѰ^HAryc&5B`T_9D&@o9VHY #8(A`$&ᡯoV39^͎Ǒ#F H b/VUag9i®Jaw*}`Hg͕6'P۾N#. )pA Lkom Ю-A[Y x9R̦J l(LI# 1`yhjm+_h@ #$f;2yv-ي[d+1R(`ɗP&ALQV0Cat;)3"⒴T^.oIJ+zd\9f̘k u|m/y˿DL00dM2r0@&Vo#)&rC|mܸNv2M2z#|BٕՓ%kPZEԡV1.e%ђ5̳tY{mqȢM-sS8S(,W#D]+) N3q^~u@(m2 M6V޵{"Zst󼔽UFw0Jp| O1aA E,\˛n2 RKucX@!.ޔO>f8*c|+HnWupGY("mmcӎzG(1v#% TWf;V+F| /-89F"hnԦdY$|Y[:!_m%)3?Fνi5:Mle7N/ `FF ,e]KdD/2:7 ӗQG9Dz5p9mq8.MMp~Fn4!1UXH=_9><ŜA`c@:@_mJ%Rx R~]LiG|!h Lhӷ_m &4eގrU6QO\ 1D TjZ!-U1[NS(UݨO7Vq߹UMuaFO"}] ݨ'YM ئXU1 V1at[1L(U3Iݧ("W#> (A 875@5ke dˑ dѢii:6;29N;m(#H?:xرy PHѳiD  8TME\F@/@o"8@zdz5Z\#etaIdeJNJdIjdHZe?d䮱ٹۈ\uY#RRN%RJUWUf5b%WV~zXvWXbhM]FZrE[~z;D L`@~a,#cfXZL6PYiO^~:#eaD^ Q]]Udް &ǰ&T\f$&aɎ]Rɼ D&f(`5d&UݥErͱAu* 1$H8ePÄf$ Z:L\\ҥyЬLy0LuS1^1ًmd] $R (2^ht md)f4z b,N)Qȝ2 &Џb&Ql(]C"Z1h$h83BQh*OR}\$}FOyU5v4Լ(MbG}V"KtV~e)^K t $ZQNv'dؕu^~Sd+nF,$,a~ e2)nԦNj~Ui)jF̪n$evQqHi^ = A S Lg=]M4&@ug#f7T*u\̙C_&V*)GҨnQd-)kXj+ j<=+ieA^1,ˮ' b!Q) ,j‚2LI+XXD9uÀѝXڐ\mGYe6`09FqE)Qbbz )lY`RzbU*.)l,vē ʈ-+(Դ-HH[UlUB-JIXuabSE",H ]5cMO1ڌ j#mѦFr(ɸ.P^́LR-0m]b{:ec ۖ!͋aLyX~%F-H HJ9 %j7j)U鸅Ap.wD676#IkU* l^\Eҍ.Ӛ.'w}2 M?G,$ݴ$0%t\s 2 27B/3*ֺ!\Y_J-P-D9ڛHq@n MC tJtII!B԰ 8@]>DHź&s}s0aNB뫾b3%S|-jU,U] lƨ1Z.ni FqZ;qeu*Mr5QQհ" .Dza*N 5Mla63b^5ju׬0W4(K OI SEN 3"$v@;͊%3:%VUr&F`9Ό<3aJRA'tnH} :֬/UM xw\u/@`,`.$84~еj jU@M ,ij6 ]r?4iendo]MDj˼5)H8ek(zeVzeI_[ t"U:$Ժw:؍d̨s WW{P;׵ohW{;׸~u$Ԧ y';{~λoWR<6"rG-Pç5Z%W<\|}eTn<+_ċ@|=||={ 8 <=eŸ'g׼{2/Γ9zft+D}'D;=W{OATΧW |V w}?C}YWzKٛ}}̴}׽W9=׮ۺz>ܽ $~k W XW[ GLeQw$s> A|뷾>Ǿ>׾>>#<?'/?> У~@W_?gl??~@??/G @?@'@`0`A&TaC!F8bE1fԸcGA9dI'QTe˓]Ɣ9fM7qԹgO?E ShQG&UiSOFHTjUWfպkW_ R;lYgѦUvXoƕ;n]Aջo_paÇ'VqbǏ!GoǑ'WNrϡG\zuױ[{wqn?|yşWU.Ǘ?~}׿~  P ,hhOScA P ) 1P 9 QLQ8`QFXpQy R!1L҄"l'2m+(K/H,379,H%S2|M8 .9,EO?TI"KsIL9-QH) UT,T3 UQaRY6UW']}U_]-X/{5eicVUkUijVq?spm]MWy\w7x_d !?-WᅉG1X9AYI.䓑$@`!!eqMelȖg9ؘu#YhXy!qZiIh^Zj@遣Z+~j Zlv[ʖl^[nڎ[>n[p6\ /p_\r#\*\t:{GO==sauw]=gq7c~\O^5E^Gc>[硯3鱥/Z2_#Yo0e?X._¿_T BDс"L\B(P $ AN@$.pI dB@,AB@ n h D$8R a?H DA( H͐f;N,.!AɢCȒ,v@p81&*b6A@.x v ::pAH(BP `X|BF$ ) iA]Dz,HЁࠄi JU\"2ID%aLȃ>$)7‘U)GԐ!8*uG| Ɉgܣ REȓ ; ɃL$;KΓ 7 p^\\ yHYTU& HfRJ='IAL-u5 @ L@%@n\%-N iX δ7%_ĂP7n ρ!J]b&/tF}Q5i>?*l_L/X +c`:l x1 `\szҖ] [61GNb1g&U1 ʒDL dD XO #ijϟp DF!GhV3s|N IFC 2UWg ?Dr|wX@Bx(\9 ɴ\%9TpqBABl!j(0`"D ̌Ċ!h*FTT$PUT)dkNp?KJ`Dˆ0JB i~HǼbGCGKG0HⲊmLd&tȉ|BkEwiIMωr*R$Ĕ )Xԡ>THt*t؋&U?h(uJO'%PGbP;PkJjU&5ȜHj`+L *2T70 hHU$L (TH $h6k͈(WT8U@DXeDobYϰYY%jZ LJjj _WKN5I5YCB^ɐ^YʊQhkQuJ?.L)L֟cJ\b1ehfmfq6guc^mbcB. @*c jHbVRiK+a$bgkhPhTpmȽhn(0ˆզjn'Wb1I`KM"mu' ݶ)pB"_rssB2YJX!rBmibrrET HuguuvbAvwEww?wxeExbq$R+xycEy$Ys6BzzazA3$A|'pJJz 86Vi@d?Zs0 NJ (pi&Md AI=G7"IBebɄ TیP8!-թ X;53bp$;7!ɔIXW h⋊X!hjJdd"Ʌ<`UY"e嶯LشT+H8T7"3JG!X8ԖdJ`+ʶjȫ\‹ =~׌-eiN^Z=Cq @j 靴hjhJOLN/Z MʺX_3;ySC $Z\ Z:%kL2 [V5Lh# c要뭨+jddoTYڅW/X&j_ºh1*(͊M lD:K%:& ;cjc ekDZG6КN% jOʈ:ɤ۫UEs]tl9iuLxJ)Ȩ6[IJy(~l!>Z66PNMH`[L5:g:%ZW p&nv lC~ko-o͍vsi:JERڌܹ˽ z&r!@w!|!F"0WX[q @oh6l85#3S[¶&|Y{;%B,ڋU[:6u9y!J`‘ y& XtMg3ˋsșȵ<ɑ5<8\77N|ϳSHXJ]9}o3$9'}0-61Mvs9E}ez=wQ}|]h<]k<]f|XLU_fDV\5?K_gڵ0`11ޒgۓ]I21\b]kF܁tPl} 1(]8l>=@>0%0$1>==@ M hw{0T~A" X b>0f? f}#`/74@/3";s%^i~/>-F"^gҾ.%b3W"^=y!e>.~#"_! ?$?5"s="#(٠h#%* ~| *^\%N幧%ȑBO"QxSHnt,lIA)j)vUeY-_GֹjIh:P̛XMBE"$8 yH%B$p`Í BHGdž$ؐ33̙4c3Ν<{ 4СD=4R0x 5ԩTZ5֭\z 6د=6m48`';ȸ;DB9Rȏ'PCǘ20$Ȕ+[9Ie4`"ѤK>:լ[0Մٴk۾;Łɜ{FvȄ]$l0pjxp b\^BuȚy>z;[o&ὼ~5/Q'!$Sr9LaD-!!ganagbl""{pa._fJCƭ <G  F Y/NIeVv^Zn{Oeb"W \[AP=#2 蘀'Jzd$z upe`sufNJ)PYi$i)if#fJ PН{Q :PhI ةm>`c=ǵB I9j>ᥞN;{`R| -v{&KnhImmҶ-R.ko+ p*@Biaw?ܬOLqŧZiq"s(& 0a,[r2kX26+ϼ<[Bmއ84:Ltx>7VPOMN5'u-t՜=TƹT^ɶqlkB8!Еog9`F5w@%׊+~֎?>]/?%v=G%ƕQWݐjb3MĦqhdI%NyC@@ O||/|?}OO}K_@{Q?:&J:fD D'I)2D,*p lJp/85 PǓ4>)M TLmH0)HBtP:BPBj tЃDt WD`buj/!ңd(l!x #bT(FE(N|u7lY b 9“mmL6 l3pj#Li6q#'GF&~2)x x0˭槝Td~]b;p&%r$1!{j:)ɘʐh7ҧX!i"od2 G$3_T&Yʚk0`11Ҿ0wv8i-o[ ; wwmnd|\w4ucqXtE$^7kk^|wro˛΢7Y:^"—/c0&%0 `&8›ak?S0f,Z wO^gK\Vľ#1yEmV],a8hq{mS;R|YNFc$#Vɔc2+Eʅ⬬e"f9B2a?yln 8ytg83/Pwy.D+#swh9Ҕt %9[V-z21^4iKzW4f([5.5tnɵ?gTT.Ph8bru䠇YOyE>d[%:0 b#%@6Y%!hRBV•S$ JwP׀CSAVwHmp+|weZEq b$7k4TIR=fӫ@ bmw( p,9F >BUX$6SX"o+HDhĒcTt8 o%9*QS>;!d:ɡ\ ^V1IX%itV+~I![̮'#!1GE`^ձ Q@ CDX~@qZ _bkIEnȋ|"|G!Zjfڗ->-H93#<4@Cj>]GW?+$t"9!wv'ӡR~D#+BFoqV q'apuWGgA!Fzx|aXWHp1!lbC$V2#&(J)Ȅ'2E;KՄ_(vOi_eHibhdhkHfhgjȆqdngp(w(ctHfv}azf|臃_eHh^xe\ex^hYdȉ`(QhdN8d芳c}HhGcDcg}`S(cߵH7]XhbH{(/[8IbN捳X({`eĎ%6S;aDɐ^L ِ 5Ia$BcFG!)3`K"#cA-/ 1)3I4)B? A)CIEiGIKɔMO Qk;;i[!XYIZɕaI!^yH`)g dGfm jFls)mqrIypEx|D~ Iqv9qiCɘB)upy@陣=I=yYo)y;f雫cmsoFɜIF)cd95. d,^1e R`0~EɟDX ٟ .!8aU *JjI5 ʡDY!*#J%j')+ʢ-/ 1*/ס2;eigenbase-farrago-0.9.0/doc/design/ParseTree.gif0000444000175000017500000004657511173714170021375 0ustar drazzibdrazzibGIF89aW  $$$(((,,,000444888<<<@@@DDDHHHLLLPPPUUUYYY]]]aaaeeeiiimmmqqquuuyyy}}},WwH*\ȰÇ#JHŇ* hȱǏ CIH 3.\ɲ˗0cʜI͛8sɳO<JѣH*]ʴSJJիXjʵׯ01HS,ٳhӪ]˶۷pmr.ݻx˷ߵvB ,È+^0ゎKLˉ#O֌ϠC;3ѨS^iƯ[˞Mmͻ+F<<ȓ.nУKo^uسkN׹`ËO^&x˫_Ͼ=ӻO~t{Ͽl$<$ d $@A aEFfe1A!B P`"L􀋃8Yq2@0bA )Q]PF٘ @ XÐ`%@ > R0R瞀Ѐ&`P )%;0!TH uvТ@JpZb!i|*T14N()hR`@P0  ;j *CN9 $0@ k`‘h/B ٩/C-+mkJa Vb)йI `e3$ 7Ù PVlYP&[d$@2)Ġ^,̤Gl =9йZl#N&r1lP2* *!)=0c(I(/0 k h  r;gXw΅jl 8:G: h~oH@+O7:l/WDzm6;qo'7jAԓ%We_܇/~YW觏֟>no1?]?nŀL*C pTŁ xGG8@ P(L W(`IC@ b e7LID @ n*Z118@@ЀH2r @4爖@ a @T i8j9Afh $qq9 (@((G `\BT@?%C< 156$e^ ѣCrP@L(I@YW*e4$"f>d.IN&VI%E )5Z0@~⏖Ej͟0!LLD̈t%49юOQKj\(9)RϙaJgyVD2i4QfHCkBRX?MjС7JUgUT%"IVQJZ/`MV (TJش%CI v1 K`[$T9:WZV:W YWXeVchW $ZA@Lh+n\PZ:3f"[)Z}LfoRگ|1ͮx 3Z,m|cs޽6'MKE:AZqj1NۖN~NW˓Tݞ.|7$q119LbJZ*4y% Nq*pUv@rHS^ wPa/5(: dc%yhDjeƇ>|c +<6 AMJfd)b^6K˓Sپ/pmeh3vkz̔\@ gIdt$Szff-c֣~:o.&QUzx~K;ϾZ4Y /!VN*MF O-鶌z4Qj95zTeLb^.^vSd|y f2W0 0ڬ "jc ҹw18cxMȥ a8XpJL,V Ào܇@%mMC!N\b5N 1A%N>GՈxnt]J٫M%'OT֠= (et/XD%p =n2 POԶu+jYx'ףȻ0{U;R;}0Z$DI9WeG:toB#v@ AjGMM!o{=^$=&#ËApz݋ވwbyGbXDaBKI r0 #.0gsg,&#SKv0Wmw4;wrGuG~W!uGDb|+}'780B P#%BvvGb.G5"s3a'/="8.k GF4L&s|V:| }PxQw.7B2'~,+Xϑvqy1#%C)(CpXʧ2Zw3GΔp8g}}(8Gp,rzQy{2Zuzt8W7(sXx}'st+93)bx=bxs(z1؋Rzr#tr&(803),+z,2$8Dف~q&'38drUwt"1ZB 'H&$0(8(%%Ru$rh(Idv/*`c0]ŒTX(8-0:?qh&E!i8 Bs8#").c!9*"-hJi+3 ,Gً#'ׁgׁ"X-g]Փ"*/f3zX+"ؔ2<Rt,b4(2rc"22:׋qQj7ɖzx(G=xJ3u=+ۄ0H'2|,j晩- Yx}v9saYF(c"L.yzݹ8AQk I(f'\i Qz 8t)8+g"0@(Rj󈞗a-BpVŒ2Œ}񹚤gp")1X!0# BpOt&~zIyh!6 .BuFG|yFG&j20F# (yשwآQ,mVY0Yx`zivC%z#2 xG",Ȓ0$.r39Z#ٖ\j$Y'a9.9 .)+(٨yylէ4 ._z٨;8]w󘌊vw>#+ojut]y %\[z/g6rs?:,>ʎJ@p&P-x"&-R{Ƹ~(0uc,eB0sr"0R\%9C#dICW'8Ki (#yF┋cL42&2ø*2y"[k:By'*FkE'G+qѫ2_S4$]˲$&!&K/H8"aGʁb`bjV+q AKĵѳ3cgf!a4b1WSce~~N[yA[r7bv ^ eyK.F:Q?>GA;Z.G CU;m>~nF@D9N.H0C;=.f2o^]&ȸ7 T=NFVg18du AxR,,찃}~! a72^ 9%SvΞ:r_.>'{hB-Ss(M,< />4,)} r C6#A/-lB:16O>>:Y !6LuG !n#X*~!!POqH}s*\2AWc,1R20Ht$ +~1gO M2Y̞/y4#{A+)"s7+ _t3ځ6R}I_/D5p(Z9$^,t,q~` ^Kf=ǟ,-|O=,/h/*`@ DPB >Q"D $&^ĘQF=~`H%MxRJ-]LRƘ3m޼N=} 9Ќ5EhRK>eTU^yժS]JdXeI`VڞY%V.հ&($H@!EC b`PI^! qPwd9䠜Y3F%;A"h!@\"q 75 )Pt(ԇ!0܍0An2Gӭ_ ;|v[cG;a17;CoH>c?L;S0BcnB o7h  > Ћ2m(4: E P,$;2!d KƁ0L|H/J,Xf͹aK9 B1% B{L/BkQG:# JPBEdqI|N~#L2AR"ú  QSn2|!8$讁(@,X v/S-0ڛ"(X[WVp˰Ω땵rTLx+9+?~e|WpGzժbW6g?Ŕ҄x\w SweTEuck"`7pg{5qAd2(эjբ?f$q##"5sFN7)%7H&y4iIUrA)I yAH- .m%Q.}Rs%m4旀YdEryf3rHii/ RMDPۣl @j69T` qy\.J )lux-@q+KXk^ՀABޕdABN`-Ukk8=- ( ZcB|{"Cjr# 6dP֦K!P &^8#d2̐8iAwy"5\V\x P 򕿲cU˰ZO𙽲dpYf 2ܑaf@`bz 40 )򡓒gYP!DɏF eLI8}QwzTHMA;MgaYEj}(`+s !9`@͓871+l:"֦6In4c+D*Kz]՟NGfZ$1RU;$)Bom{@IMp;dQx7r(%~RT{$H $`;EW71*?n;6BokL;E(D(S" |`po$#'@TlQc4o7t> H@(l5 u?3w]4K$3 1rwpm{fj@(5Okd{y'WoCd G. g ;KOH#Bl{x葼Q`?0Éz gg(?@>(>jk0=vX @= c8@2+;׻Ϊ0+@"qrA+A{8k@" yAT#G{$ %$:43zy@ij‹P;"T1< 8C(C’د7k5ol&8$!` +C3W;H;2 ǁqFFœP[qdF$I8A8 !HwZ,u4i܈&fӷA]ǎPpӀGAQGM4vTP39C4Q40( ;0g~,gH/*aɌH =\1ڰ3Pɕ@2ʕ7[me)!])44HJ"ʎG[RK[I(3yX,byLJvDLԤt#83I@3G܍tLJP6SrIU2ͪ k+I أX ɑL`< ̯;<< Ԭ d=R{ еD O0Ͼ KOcʁ; B*0xO>+,sYǃ7EQљ*2<|BҎ >|W#"=팪 Rc:=*YR# MR>@C],@F H pI],v 7H" ΙRSP ¢TUU=,O VYETPԮTI`#c[MS=UK}U=(I܄cihuf5g}e9b!әVP}b]d֙0AWP׈^!:ݍ )F: {MQmsRW صX`AG!bzSמ89q5MU uR9 )} -=XYWSX 5eam}xm ֙I-$^M՟x[ZxZVJ3Rz5 -UVw-9ٓ}+}c P Ul\A̼<[`\cP(-U@ܒP\xo44-מ ۀ2ۄ{Ε?]-^]YX1m\%H֫߃#<M|_?\\TIۿJA`)pzGG0G$⡷ʻ8S߽% (=D`TmyjUC\7/2|NQ rp$>y)hɕy u_ 0躋QQ$]_aa pşxyߙ(/J- IG.Вd%ז ȗ R9^9]>ߪc%q^&* &C+aРXb͕d*᛼K,W&e} (M05i=>RVBf'bLTVe Nfpm4,a]Mbueeʀgp¦Zp1 f\Yi\ D@L&\Vg@(gٛ9Zh e=n v֊&ywT2eީjjJdiҽQiP_N9NW΍^g:f _wF0[-O`O.jP^UlAc kv41iVBթO \h׎LKlpjj_,4`] hPPn>y A-\fhI+ы)| 連yʿhUDE(o?6f ?20 mS'pon^W>SƉ 8(7g zhpPPɁ J 7]hg8&6 ~MW7 "WA6! 1eq./*' D"oY*Gޘ2jRBs͍$[1-:Nr `tG8o tpنtq=G όJbG 9BNxG] E.SBuG !y [o d/$ّvu~RטvEMߴWHequ8' +grwmTvz`n 0,h@pe3)^J#w^^_טO_*~ ~Xi3ABq.#Cxxy?AgwpWipXv|OV1 7#J W ^JYwdz5y(Q7'AZ' ? S!@ɞD WGO1'boujpP*W(ꛞ{Gq$5@Hyʣ 2|hE3xpuf||pVH}/A1Gox73Y>{D~)ՀO ` 7 Lj'-33~ A~0` "v,hr l!Ĉ'Rh"ƌ-2x#Ȑ"`p$ʔ;lR /b(1&΋V3“,j(҃(($mӜ,RhͪZ5uA-ٴs 6Էj̚iʕ;#Ծk\Jx0 /]Oea^^]3hӊԪWn5زgӮ]̺lC)|' ArN_[8~ڷs;Ǔ/oC׳ xeӟaiBoZT |C˅F9X!P*hȠTnbE8!8#-}5ǖ(#;PXdJ@"$*0I1iڐ*)9.b ls5` A p]RiFxi'fMAXgZmZD/0@(Zq Vk'YiD)=ݘC7)Y$=*AFNBХ%KVz +dFHɒ*:;yF״>A;RBǔF6R.m뀎i3;R ܩFDpK:İj@Ĉ[EfS9 <1nb[tǮk{A`@| cr. Ap.X X4W;˘`1@M{ݵW9oo''ʢ?:> 993hQV(%9Hb( c( jhp6^ y"87ѯ("qN^ $F GiÒ4ML5ǬHF=tzTqFqZHEȑ (!$Nِ/#8 + %I?b P 2H-kyX0$ 6mo90@ԢIy2")H@l "$7h$'AL`$QRlj3@D΃$@F8>οMjd&R8L~ET+NP @ ϋ љ&Jt|>-zF2jDJ2&>NeH? t4ѐ(+IY !P 鑑ʠHn5lHIgrRoA0&Wƴ!4݁:MT5%J˂#AX!KdjlST "zfSf7w6|iV4H\_2׋:! :/ `{}Z%al h rAKpR8&A0Ժ*.©OsdM/R3(n6 K`E7ZT~|" Ec̯o-Ky;މR3dpVo%EW[$B| a%G5f lӉ% jO4xvL KɾU->[.7v#)A=g1/~Q5+"v3;Urj[ j`N% ͛ :#Unɕ5Uft~se$h Kڞ3AHPOl2/Yʗ;øSʳCBD<̓/8_EF \c7J2=65OQ8+P]QbvբmțٴLe`h="\!=a_;e'Lqjwxtǖn0.Qr݃|bw-h?αYn$ Zh/Yo%xEW{쥞yX Kp%dw + -ZQS퉴~&VtL_N=n+7.;#.O֊2<*ݺ5!ʬwnGHLūo|6ӭhp]3/9e۷G:J>q6ԘZF~&6?.TGvuY.EͿ"26]( A1nҖD2p ?}4&w ?*7P7Ri_$x+GW{0gdi?\ E IҔU_%GrJu2~DIBJ-} V.I n H JiP & "I j HI}BM:G ZL[xK[e!)]`A)uę9QURAmUE~"D;Y|dS!|TU !EYRDfD [9%EL:GbH*’LNjݴ,rA"HtS6MM/D&b&D!ڄ$!O x=M+*j+^E"ib2J\H9Ӻ θD%Pecsׄ#+!5P:y:6$;4`Ԇi$r0d~YܵS",sd|idA]eJe::.ʈYNG,#c8EMu$!eS$s]A6S䂼!]vm:Յ\ܮZdR|SV@-?UvH9 WƤVB^;BMaLDWyFV䄹QrdB$&&E(E4#HeeD^6aL__`>DF :e B8VڥA&PGSpfIՅfN$]"iQt8&gu0C&ZFӍcFУp'28G<1)Zi\B)˘ iiiFDF`fEhfH\*Fd*UiThdp*h)iI"4aOڊP**jDxꊐti ܀8}*Dkri +\`s@kDHPh@pkh :+Dk+`%A nkQIH , .,}8NȾJGn"Mdžн`f:kl@0@)t-m.KM+(2.آ,ĭHn~E,₮ 픜nj&J BƉ.j"K 6-[$V-kP/~oDΪ:.äo"V@ -Ɉ@ PxoώO | o0` $,/ v9 $M(p3  .l;!p n@p(Op#0Tp"  ;L TFTJ 8C1|TǮpLYl11qPK0L@p !G\"@ D0cfHpio/F10;D4C1cD2k2O83kF547D8#5_D6g6#7b33BsE33;=3<?׉=W>W> ?` 4ETqrA8t̡WQ4Et&'EDBcD |V`M,4CE?D e61x^D2^ hFd154E^Q9(FnI6udGaS9>tzj*~!% @ F8@3*J"cG2HpGʖ0 k$%˅ wha8 L(3 rT S&͇:!&)DKHw(N+!d(c"Ѫ?|8]c 4ڗTw̬yS&XB t9(гӪ+p͟A=tiӧQ4) ةGvߎ 5!EN ]1W#ʷ(\ JS~kd%Ի3)ha"Kā;>` .,\̻ګs.3I껭o(23XlaQ+lcC0`6#Hȣvb&l $B9+ jM εL°19ǯx!$P¤ܻ,.@((- ZNcK '@Q +k-\s/20M}ތS]O=_ Vaʒ4:騈VH!Vk9"aYK5- 6"(@$`+=24W"(@(,O@Zȥ`Y BX fxZ [{OĪ;RWĒ%ľ|[fX?+7Wy뽗:f_*wOFX9byZ뭹*wck=MEOF TDu1K~Q;*;Up=-n^AE%J9so?#,QAc4UR֙{[\v6߁([4u`O^F%y{FьHEou-/?o'_~#~РHE>fK]B?_wU1X@&1$d1$wDH-$$ЅXGd+g DvV+NՐ1ra2Ddyi@VH q;|lH>)pi]@?B ĉ. B%2q%y‹GAbA W.8,f`j(Ny6ubKpt5]㍸$ȱK.aF\'8N%AO BG\PXY<%֢*#DP-\#)ݘ.sQ #~B!f 4WcDf<ڕ:wJ$m,9D8\et*\!($4-hϴPTUȦaR$`?;i"DhD6;:k\y; )ivEށa`MR *RoXm,5A)%mRU>&E=%*V$S0d':4$9(JG񦰐,]O!F=$&YZcTٖiv1&8jb$@b :Fg`b[18Q`JLn&^ knQv Vg+Qr5&;%, k)+I|0".CBe&NZWTǔ#ڳ7 8K>0x-LR(S 4I7Y*zXz PUd)h5-Չ-old`}6KxgHV"rj'%ʷ.]5k4ՔI2,Ƥ[ECӼ˅Oa*r2 W[`xؒ~(Rwz z6I5X&Q˂DEXXLIKjN.#/,J`*FOZ˘uUBY 9ɫmkZe2ـf,c7 ,HZ1ni:4ѯ"̺z=ܩd#jP 3I{U#ǥI¤R?q P{"ڶ]Jo 6:V{In}7؟io-SB9&RƜ/FR8UDn%;t;)=Y{{ܑ?u%<`$И,K$$T6Τl!]/Lkf_3Hυb . 0`H #<+'uDмONH'_(NK*=pB0Ж'uf|(⊎ʮW*ttlFdWLMpp4Xܸv"'}jƂ= O ~pF)p a hk"0ݧ y͋/ 5QG Farrago Design Docs

Farrago Design Docs


See also:


End $Id: //open/dev/farrago/doc/design/index.html#20 $

 

eigenbase-farrago-0.9.0/doc/design/jni.html0000444000175000017500000002435411173714170020451 0ustar drazzibdrazzib Farrago/Fennel Integration via JNI

Overview

The architecture doc mentions that Farrago Java code communicates with the Fennel C++ kernel via JNI. This document presents the detailed design for that integration.

Design Goals

The JNI interface wrapping Fennel is necessarily quite wide, as it has to deal with a variety of storage objects and operations which will be extended over time. This implies that the interface should be designed carefully with a number of goals in mind.
  • Programmer productivity: JNI programming is very tedious and error-prone. Everything possible should be done to make life easy for those who have to define and maintain this interface.
  • Safety: JNI programming errors can result in undetected corruption of the JVM and/or the storage manager, and weak typing makes it very hard to detect these at compile time. The interface design should attempt to counteract these problems.
  • Expressiveness: It must be easy to exchange complex metadata between Java and C++ code.
  • Documentation: The interface must be well documented since it is accessed by many Farrago components.
  • Integration Completeness: The JNI interface must provide integration support for all aspects of server execution (e.g. tracing, exception handling, internationalization).
  • Efficiency: Interface methods which are on the critical path for query execution must be implemented with minimal overhead.

Approach

A well known approach which addresses most of the above design goals is the proxy/peer system in which C++ code is generated from Java interfaces. For Java code that needs to call C++, the developer fills in implementations for generated peer classes. Conversely, C++ code that needs to access Java makes calls on generated proxy objects which wrap hidden JNI method invocations. The code generation step addresses productivity, safety, and expressiveness.

Generic tools such as Jace are available which automate the Java-to-C++ code generation process. For Farrago, a lightweight homebrew solution was developed along similar lines, but tailored to take full advantage of available metadata.

The approach starts with a UML model for the data structures to be communicated between Java and C++. This model is a subpackage of FEM (TODO: link to FEM docs), so from it Java interfaces and implementation classes are generated automatically as part of the overall catalog build process (TODO: link to build docs). However, these classes are marked with the org.netbeans.mdr.transient tag, so instances created at runtime will never be stored in the catalog.

Once the MDR-based catalog is created, a custom C++ code generator is run which produces C++ proxy classes (peers are not yet supported as there has been little need so far). The code generator uses a combination of Java reflection and JMI metadata access to transform the source model. The available metadata allows us to take full advantage of the type safety afforded by C++ generics. For example, in Java, an JMI association is accessed via a weakly-typed Collection, requiring typecasting. The code generator knows the true type of the association end, so it generates an appropriate instantiation of a C++ template which hides all typecasting. The generated classes make use of a small runtime framework for calling JNI.

TODO: diagram

It should be noted that the choice of this model-driven approach brings some design goals into competition. The extra complexity of dealing with a modeling tool introduces a learning curve and may add a small drag on productivity (although it's still far superior to straight JNI programming). However, the benefits for safety, documentation, and expressiveness are worth the extra hassle.

FennelStorage Native Interface

The only Java class which declares any native methods is net.sf.farrago.fennel.FennelStorage (TODO: javadoc link). Only a few native methods are defined. The most important one is a generic execution method for the command pattern described in the next section. The other methods are special cases for efficient execution of tuple streams.

Commands

Execution of Fennel storage manager operations is accomplished via the Command pattern. Java code instantiates a command object describing the operation to be performed, and then passes this object to FennelDbHandle.executeCmd. C++ code interprets the command via the corresponding generated proxies and executes it. Here's a UML diagram of the command class hierarchy:

TODO: links to detailed docs for available commands

Handles

Fennel commands usually need to refer to existing storage objects such as databases and transactions, and sometimes create new ones. These inter-command references are accomplished via handles. A handle has two parts:
  • a dynamically allocated C++ object which stores the handle state, including references to other underlying storage objects
  • a Java object (instances of class net.sf.farrago.fem.fennel.FennelHandle) which contains a long integer representing the pointer to the C++ object
The command model defines associations which allow commands to refer to input handles or return output handles:

Since specific associations are defined between individual command and handle subclasses, safety is guaranteed (i.e. a command can't accidentally pass a transaction handle where a stream handle is expected).

Commands may refer to more than one handle (e.g. CmdRollback always refers to a transaction handle, but may also refer to a savepoint handle).

Complex Return Types

In most cases encountered so far, complex structures are passed from Java to C++ but not in the other direction. The current code generation infrastructure supports proxies with limited mutator support. Mutators are only generated for attributes with simple types (primitives and Strings) whose names begin result. The few instances where the storage manager must return complex information are special-cased, e.g. by constructing an XMI string which is transformed into Java object representation via the MDR import facility.

Tuple Stream Definition

One of the commands, CmdOpenTupleStream, deserves individual mention. Its single innocent-looking attribute, tupleStreamDef, is really an entire submodel. Execution of CmdOpenTupleStream results in the construction of an entire query execution graph of specialized TupleStream nodes. The only graph topology currently supported is a tree, which is why the Input/Consumer association in the model below is 1-to-n rather than m-to-n:

The leaf nodes derived from TupleStreamDef in the above inheritance hierarchy represent instantiable Fennel TupleStream types. When Fennel interprets CmdOpenTupleStream, it walks the recursive TupleStreamDataflowDef association, constructing the appropriate type of TupleStream for each node visited, initializing it with the defined parameters. It also ties the streams together into a dataflow graph mirroring the TupleStreamDef associations and returns a handle to this graph as the result of the command.

Tuple Stream Execution

When a TupleStream graph is executed, it may process a very large number of tuples, and in some cases, these tuples must flow through the Java virtual machine for filtering, transformation, etc. FennelStorage defines a separate native interface for this purpose; the interface is designed for efficiency to the extent allowed by Java. There are two cases to consider: Java processing of tuples produced by Fennel, and Fennel processing of tuples produced by Java.

From Fennel to Java

For this case, FennelStorage provides the tupleStreamFetch method, which takes a stream handle and a byte array as input. The Fennel implementation fills the byte array with data in the same tuple format used by Fennel internally. Tuples are stored contiguously, and only complete tuples are returned. A separate method tupleStreamDescribe can be called to retrieve a physical description of the stream output format. This, together with java.nio.ByteBuffer, is used by implementations of net.sf.farrago.query.FennelTupleReader to unmarshal the data returned by Fennel.

From Java to Fennel

In the opposite direction, things are a little more complicated. First of all, the stream definition must tell Fennel how to call back into Java in order to retrieve tuples. This is accomplished by specifying an instance of JavaTupleStreamDef in the stream definition passed to CmdOpenTupleStream. [TBD: Java object handles or class names or whatever ends up being used.] Fennel uses the attributes in JavaTupleStreamDef to locate an instance of Java class JavaTupleStream. During query execution, when a consumer of this stream requests tuples, Fennel makes a call to JavaTupleStream.fillBuffer, passing a ByteBuffer. (Note that this call sequence bypasses the usual proxy code generation infrastructure for control and efficiency.) This ByteBuffer is actually a direct reference to C++ memory compliments of java.nio, eliminating the need to copy (TBD: why we don't do the same thing in the tupleStreamFetch case). The JavaTupleStream implementation writes into this ByteBuffer via an instance of net.sf.farrago.query.FennelTupleWriter which has been provided with the target tuple format. Once the buffer is filled or no more tuples are available, JavaTupleStream.fillBuffer returns to Fennel, which continues execution with the consumer stream.

TODO: diagram of a tree involving dataflow in both directions

Configuration Parameters

TBD

Tracing

TBD

Exception Handling

TBD

Internationalization

TBD
End $Id: //open/dev/farrago/doc/design/jni.html#3 $

 

eigenbase-farrago-0.9.0/doc/design/FennelHandles.gif0000444000175000017500000001723511173714170022200 0ustar drazzibdrazzibGIF89a , ڋ޼H扦ʶ L ĢL*̦ JԪjܮ N (8HXhx)9IYiy *:JZjz +;K[k{ ,N^n~N/?O_o/ 0 <_} }K1ĉ 6!;1$-KRW$C%v[\ӕMƜR OS՘$Z hPJZ3״XתnZ]WTYq碕._na;~ :K҅6\l7W׮ŌO> 1A7 Rif}Ywם DsT[WqQyK~9ػ yU?#g/|~n`4&>w]2LRƙYf` h8ၝLXbeׂG!})Y܅ajYsY6ؘh7㊙X~YFm@Db靸c=xɑJB1 P"%=IF^cNnIc:7kfzdxgH{zn] Jzm&*](9F.h,^:ڢB),8Jjz~n)~*I*B}_DZI(Eރ=t,J-({T_q|%bZL˨ rF$rm nX[1Z,rNGCM.0{11 m +y! p+Korœ[oa,t#ۀF7 V`S|VPnMr6>]&Q .4U"c?z dm(Gєp^(2qNd  s֓:{aFZiURZ۪)y%+0gvJU9ejQf`isLsY.L+{F׻ ,m%x,r&o8_L)lNS987]  gjK ^!z)^V؃-L[؟7[6lbA}j[&;NS{!;L$3/#8z\pЫB5.ђ#َw2!r qDn[0!ϜYƾYcj#Ӌ]hrL!8A}Hpմ63},w6j\A[64 #a *<8|WBeԳ}LV;zXh6:f3]t=Xxf4}(5unaFK[EoB>&}@[yV\jeW;6T%Iϻw𪀛z^;:\ì>kpKqdqIrX|)oNny0GonjaXz ĉ艺wX ` ' dviweXv؋H`ex8VxY<^6=@Xudž]草f"ufcbcu:jnQ+{A8q8ZXmSÆ'#Z^7&mg8 ۈ揂e:UtL6m4 y (/6\JV49jm$TBfQ?+P\YUc:hUS4"xxGrƐWIzM;WkPY| E[blUӕZ#9n`y8 fٖ7hr9Kx3΀zl dYVSvHpxu,"yҘ(D?C{闤E /iU8['4GYxDtYO3}ih@i:K&C }[YLYl%Ԕv.vkTˇ|whƔAEo9鉠kdI):ÛIf t~ToJ(QC4(9@KM,S:WYm%97ie3d-6w/Rs:KP%s>i9\:6FQ&MB3MTڞgT~k6nF?)Z/4VTډx:T/V~ʝl!N'¶rʂq6**x78iQUcU#c fIqڟ"Ȣ J]E4JJTEʪpcdkhM=ڍvڪf^iVc=ɬBi fZ)`Zb@EfI !b 9"ݪ `菼5(:d'eN=Ev5Z:[& 4;;+䙯䪚 ˱RR7[} Vj L ١Z۲Tb بo;-JquLG$:&!0|G~'[qЪk#weO҅lֳԆ4Z`&f\~k dڒSuenIK;9|jèjzk Mdkd|$;:ֻKqیzې[۽j{ +{{;KpkdqG;Fţ`t˚V\uKGg,t = s 3'rl)LrRC!,!D%2w+>-ާ13L#7|<9Ü=,?6 &,CkEI+KīO)Q,}uU܄H/<[tW ya}zegoc& ލ[mއGhF2ޣp܏x;6=w;ߨA·S8љV^g8E,ٜ޾6&^)Yh'[#?;>ƫݶ %72~'n˟B~߶,IMΌNIM&L٬ J6]ͩ]ꂐ kt!A}o,Eq`q7(NAN ][YD*+!O`3R ( Xsť-R/ׅ:a_L;m 0 rVt ,U?2KWٌX;/iyŨ喪K_n@,P 6ʩXռ@˫QNɧ+ѷlځn4Y (*W:D1g#9<&* 륙:<:u[.C,4x򈼸G!}Tf<"DN/k,M;%j ^.+Էu2>:˹_-__#5o+UݦjQKlyek讫9h\Rݣ{K\؅3k^A?ԒkD+n!Q}N_qk@z {BfJk]+XuFWj҉7?[/m{QHv~ա߃|V ŹϮ_Lx-hPBy OQaV{q֛w%m^Yl3Z\6si) jqs߯: e !#?+]50%79(-AS4;IK?CSFIL]_dgikmoqsuwy{ga}}sX#99e)'_Aɉa!FTpAz%fԸE 8d- ڈtdK/Gx֒%L7qVWɚ9 PG",iS>:*UfjV_ ;l`]ͦUZoƍ'n]6ջWj^ pa'.;XqcG̔d˗bּ'gϟ!V=t)ѥ!Suk[*`f㔝;m߂xoB\/5?,}Y-\R뒔NSz d:43|W ˽A̎Wo=OB0A.F$A78 =_1=*p?A4?S{|DmT2#IHÑBqQA.cCԒG0wJ[z6s8ÃΙOvO茫B& 4FK;QE"G'4 I'@/մHIT>MIQWSARPeUoHUX+3~Uµa-6`]y]DYdfYiVjZm=nCܐūIM wXvޘ䅎{k2r_s (xI&D 5 $ע25'#;ф'@+&1X&cBzI!F^@gmƙ֝֟1f_b1_.SAŘge0:zdj=j&ֱmxR꽧 F{›E)ںk6kpDpT#N|躇Zosgȧ•EX+C3I2jŲ'rpM+@m ]}zcyѮCQAG]sה+:ե 5jROK՛1uPVkZufv֛ut{la6;eigenbase-farrago-0.9.0/doc/design/TableIndexing.html0000444000175000017500000001607711173714170022411 0ustar drazzibdrazzib Farrago Table Indexing

Overview

This document describes how logical Farrago table definitions are mapped to the default BTree-based reference implementation known as FTRS (Fennel Transactional Row Store). It is possible to plug in other mappings such as column-based storage using the CREATE LOCAL DATA WRAPPER command.

Limitations

Every FTRS table must have a primary key and exactly one clustered index (which need not be unique, and need not include the primary key). When a clustered index definition is omitted, the primary key is used. A table may have any number of unclustered indexes, both unique and non-unique.

The primary key requirement is not standard SQL (even though it ought to be). Eventually omission of a primary key will be allowed, and will result in generation of a hidden system-owned surrogate key.

Example DDL

We'll use a single table as an example:

create table ENLISTMENT(
    NAME varchar(128) not null,
    RANK char(3),
    SERIALNO integer not null constraint SERIALNO_PK primary key,
    PLATOONID integer not null)

create clustered index ENLISTMENT_CX on ENLISTMENT(NAME)

create index ENLISTMENT_PLATOONID on ENLISTMENT(PLATOONID)

Since unique constraints result in the creation of system-owned unique indexes for enforcement, three indexes result from this DDL statement. The constraint index will be referred to by its constraint name (SERIALNO_PK).

Each index has a defined key which is the column list specified by the DDL statement which created the index. For this example:

  • The defined key of SERIALNO_PK is (SERIALNO).
  • The defined key of ENLISTMENT_CX is (NAME).
  • The defined key of ENLISTMENT_PLATOONID is (PLATOONID).

Clustered Index Storage

The clustered index is implemented as a BTree which stores all of the table data in the order specified by the index definition. Here's some example data as it would be stored in the clustered index:
NAME RANK SERIALNO PLATOONID
Boyle CPL 1004 2
Carter SGT 1001 2
Carter PVT 1003 2
Lombardi PVT 1002 1
Pyle PVT 1000 1

Note that there is a duplicate in the defined key NAME of the clustered index. This is allowed since the clustered index was not specified as unique. However, we need a unique locator for every tuple stored, so we introduce the concept of an index's distinct key. For a unique index, this is identical to the defined key. For a non-unique clustered index, we append the columns of the primary key (leaving out any that were already referenced by the defined key). In this example, the distinct key for ENLISTMENT_CX is (NAME, SERIALNO).

Unclustered Index Storage

The distinct key for a clustered index can be thought of as a logical ROWID. In fact, this is how it is used when an unclustered index is stored. Each tuple in the BTree implementing an unclustered index consists of the unclustered index's defined key plus the columns of the clustered index's distinct key (again leaving out any redundant columns from the unclustered index's defined key). Here is the data stored for SERIALNO_PK:
SERIALNO NAME
1000 Pyle
1001 Carter
1002 Lombardi
1003 Carter
1004 Boyle

Note that in this case, adding on the clustered index key does not make the unclustered index key "more unique" since it is already unique; but it does give us an indirect access path from SERIALNO to tuple: first search SERIALNO_PK to convert the SERIALNO into a NAME, and then use the (NAME,SERIALNO) combination to search ENLISTMENT_CX, which stores the values for all other columns.

For non-unique index ENLISTMENT_PLATOONID, adding on the distinct key of the clustered index serves both purposes:
PLATOONID NAME SERIALNO
1 Lombardi 1002
1 Pyle 1000
2 Boyle 1004
2 Carter 1001
2 Carter 1003

In this case of a non-unique unclustered index, the full tuple stored in the BTree forms the distinct key for the unclustered index. To summarize distinct keys:

  • The distinct key of SERIALNO_PK is (SERIALNO).
  • The distinct key of ENLISTMENT_CX is (NAME,SERIALNO).
  • The distinct key of ENLISTMENT_PLATOONID is (PLATOONID,NAME,SERIALNO).

Index Coverage

When processing a query, the optimizer chooses an access path based on what indexes are available. A filter on the clustered index defined key can be implemented as a direct search against the clustered index. For example,

select NAME,RANK,SERIALNO
from ENLISTMENT
where NAME='Pyle'

A filter on an unclustered index normally requires an indirect search as described previously. However, if the unclustered index "covers" all columns referenced by the query, then a direct search can be used and the clustered index can be ignored. For example,

select NAME
from ENLISTMENT
where SERIALNO=1000
In this case, SERIALNO_PK can be used for a direct lookup.

So, the coverage for a clustered index is the entire table, while the coverage for an unclustered index is the combination of its defined key with the distinct key of the clustered index. Examples:

  • The coverage of SERIALNO_PK is (SERIALNO,NAME).
  • The coverage of ENLISTMENT_CX is (NAME,RANK,SERIALNO,PLATOONID).
  • The coverage of ENLISTMENT_PLATOONID is (PLATOONID,NAME,SERIALNO).

Collation Key

In addition to coverage, the optimizer is also interested in sort order (e.g. for satisfying ORDER BY or merge join requirements). For each index, a collation key can be defined which is the list of columns according to which tuples are guaranteed to be returned in order by a sequential scan of the index. For a clustered index, this is identical to the distinct key. For an unclustered index, the collation key is identical to the coverage. Examples:
  • The collation key of SERIALNO_PK is (SERIALNO,NAME).
  • The collation key of ENLISTMENT_CX is (NAME,SERIALNO).
  • The collation key of ENLISTMENT_PLATOONID is (PLATOONID,NAME,SERIALNO).

End $Id: //open/dev/farrago/doc/design/TableIndexing.html#4 $

 

eigenbase-farrago-0.9.0/doc/design/MedStructure.gif0000444000175000017500000010273411173714170022117 0ustar drazzibdrazzibGIF89aԼ¿)*)999ghh[[[GHHyzz¿MRRNQPluu|Zb`/33^fe䬴?CCqpq""𱰱iqpmpr,H*\ȰÇ#JHŋ3jȱǏ@Rȓ(S\ɲ˗0cʜI͛8s) IѣH*]ʴӧPZIjXjʵׯ`Ê}i:۷pʝK.ؑF ݿ L@E0RÐ#KLX5;`ϠCMtKk;+& Դװc˞]8q6w` >䂪켶7УKسkνO &_Ͼx~ oH- ؐv!H 6 :Q Q(f !}Xn(aW,(#t$@֥$ _ @R;6CD#-1PNI3)&le``*$A}0-)Ak.v'P&B}4%y @'1QcVjez9"0 _T2@t>R]22@B p 0@j;,y+"DkݷU N @׶+,ګlpl\ ԙQ:H\8J0+Hu31Zp Ċ+A $(ڦg1+sk]_,l%ol{P9r0{(@?|m"3B:=4+D)dmvMzPn;r}ۭ@Z&'L&se;u!^ ?xG64DJ$8;n8~39s|w|؇~ڰTVU~ɸvE`m pwQKN|kJ {q3kI\C(NkLqgWnwi*n: <U+;BjI^T'#9_A\6P-QVz) %3Q=q t #APpPq f¯ouQ}ڷ,97ȉ_ifědn%|# 2JR,ԐP3 Z!jORٖ5YrOQbKDvRJ9̏!mj|7+6,! -7Ls.&cΘ̈L G pe957 ~TZgvi`b"լg*z_vF*S^z>LΔA GgsabmgVG]s"pLbiF:2S NE ``,=v>QI 坭RF;[ŹNt&ݝTW&Lֳܰd uhr!qDvԣ0Zך20~xcQmR A96)NszX+7Gz@Ћ$n%քEog b7+'%>:uuD]%VJ@u$ː– -C E]e$+ Qהy@a Tn1 חX3IT\69{Q3cƌJvm[,Y^= H0@3 ?r7X/qrD}K#~p|'oؔcu5t,?,*1-Tkc^/[oſf2oہSunt9k߽V <˵~M]_<8W\w{ '/9, + Pvf,~aqj_[bu3N^-pnaضS. PAǨ~`z7/Z|O C%>kz 59čTx}QyWcuL& (6{Xd4p9pFA4|#Jֱe~0D<#3.-FĒZav +p7C47fB,$p5BYeB~8C"5rb&z}4E[Ge eTH'T4WXpGeGhkH?8O@#nw`EMte92XWi@aViW 2p,GX'ȆpuII'P!TVzk2%r4k-sc"i!daFk4RjH>YUmse -]0&؁:~1]6)N; ? cP c*$瓡Fq"sO ^Y`6Bq+M8m-Ey00n¸6 I@UyɆK(XiYH~QB{fK2OfYiMOi2"rx)b\t[e_%6HQ/'/'>*)+F,ǒFd~`wkcz!orz8jutDJY"`&zɗEÇ[A|՞ &S gɓ/2tSP1ɆMIMJma)WQSOj1bbW_gZ kC-F! ":Q |pI,ʌ(Uȱ<a|r !Mb`šc>ĘD3j]0;Qth EI 3N$q3 Q-\QѶӧl$IMYǶYѪĦ뾷%(FzJ?Q+]BLK=T}W]jȑČȜLdz} V8,a!a^b]!পYi>%>rԐ**I2ťl{{|]@ۯH\QJlç:9?ѕa g 1G.綡#<yŘBZA_C8Q  .=5~6J.n{͆ጾeb)-^ߎJQ~~w"JgTuƴ0\wZ~=$N2ѭ! Z\|^nN*؉dN͂AVA @۶`xL؏'|h~FeZatP٩1QB\Lڱ-;zDU+G>[l Y?a㜛w0-]i~tg'OJz$0dR.n4Q'8Ǟn>,&m(yOLȕZ=Ѡ o?PA}eo?L1//#o\1DD;عqohHHOJ2OLap5QR"| 1a 0@…)V0cA=~RH%MDSL5mn\@ԦEE:@ ST VŊF ,၅4@H+طjM88ž t  6"ač(Ydq"9sΝ} ^$Sz/V \.Ȑ `m׾}ӴҍX3bǚ ( <  Ƚu \؛|I%G^<sQ+>%g3{ bJ$ 2S7Bz 02@V.$ę䣏!WFd+JK1/0`$cGB7Jp ϥDj-&LO. AL dq"3FL&,jGls: r@)p &%"kKꪷAE1L9Ӕ*#R#b($(T3'ՠ R0~ӰZ=:bKE6O1t)CɪJ(JJoJ9?jtM8+{sR6_iT_Kڗ 1F8af$J I &5&fƽxb>eWTNS4ʥI +:S ԨS/M:7{Z:lKḶ|CZ\O`Es%(ׯOn SiG~<7'mnHKïE[`a=]諬!rЅRVohrq}2ݩ=9GZ[sò%\zh́@wڰJ%wGC=9 F8_|.!@" [VEdo;(qHX 8w;5oA۝!}#0<)uMrWCP|Z $ $G]-LX@wI Gx% 52Q^CqHČ8fQ% TaF-juB*P*w ^<*JK21lm<#%C7Kn%Uh*}g \27+R0AԤKZDI$ 9 PЕ%oaGheVmo2dPT - O '4Ҁ @ 0mHmv 8~>Yzҙ ]4{]4 o6y r DWFK(@ET@(09y3e^1 L+zDVxJ8H2}@M.B#%H!tZ)lU:]Q͇Λ44srSn5hF{nRՓS=d >(} __NkϥR=i`Q!`@Z/A|2o[;~tw2+v%(L=\h4B !97)!#ѶG$z 17Ҟ,ABA'1=$A~\ 7-+lY5>@tK7Lٿ3@E[E}I.?P󧒈ᚰ"p7'LC á3/q=i̗(QDE(p9ЀY 9ě; GFFkT l QlyFT92&9 x +2| 9KHJ jHd!Pl-|X!/LTN)Ff ,Z)S,KEI(ɓȢ,DIh?RHiGIR(y߲GJAT`ʵ,=@xFp$Ҹ96}˭P/HR sKO!lϊm|@ʻLʖY44 +K L@ʋ*EƤ8ƔLB1UL`{ wI(ŦU@:ܬ=@-I09B*x"` ,ڑZbA q?8ː$&m";\Lܞ t ѤނA21:@x TK`56qeu5 0ͤ8)YG +JA*pO8ҦB5;+Q Pr \mi {RB] 3C3R~M/ͻ8PKǍH˟xtI͐GC*KR.L>^\PԐEɫBT Uu8 T: i3У(& FkTTٟ\,mՍU7 SʔE6m!65Ւ~2F~)h/i-4($R-UYmUQؑ LB41T4A2``aX0=ӅH3uC 0.3PАn ^%Dz QМeծ[ LJ1 Љ(-L{]씌*.E\8i\ 4E ;F KYypۧ5JG4 Q0LBVܮuYH QyH-5e݌`  6ڬh64XTV>`ZX[. b V$U40 F0` `h"`)j[2mੌ"\zT!ݯx*5=\k-T1=9\ -c0V[=0&K-{02C$U899&")zS@hڅc5/)2nC<7P 8dh Xx*TnZ(Ӽ=KX-c)V[Y ҅e0c.~eȠIا0Z =m>m ENn-nOK5&`l^!JÀDШ0 ],߰Nоbt^jT-5UL XXL+ ig ݉'1 㴴g#0do76\ofgF6P:[)jjЫ9` iP И`Yn!" mS8 'Z`Ee܈ꆘhbe<lc- P ~f[`")e898 X `1]." 8mVOV0;կ9f1! 8I!7؟=8h=LQan4z: 9#+l:6)S[s°=p$e]k3ifg6+m(v le|ZSk.)(R-]2A۾6q_ƊϽ\T a`g~&~͖Xa<_eڂ`&35 RͨS)9I' GFc&u҃ tN4G[Aq͌623'ѣB;n_"u@-LI%ЦHYq@*8ӹLZNϋ÷7Q6(^!W=>jAnPd['\o$TӦPզ w筵1HuSOi$j_FevH_^tύfp_yV{CDB xûX ؙx7I]dᏙzИQ\. @G*= *sC![>(0 _sug˸z zGm'۴}Cz^ɳ b 6rW35Vǧ8f8.XU2_8j E>ލX|\ u{ȽŒRzkϒ@7x ! |ЗKэɞψ9. i3~i{6~Ԃk'jP~j1 x6ɾv$i3VO ʝ /h „ !Ĉ'R8Ѡ@#H BJI$ʔ*Wle2g2|iI(nyӣ4f/b X``Ɔ' Jia&H9nmJLFdNo7;ه&:@H w ̞4ѓ(:q"@ԭ @!Ab@=wHFwA܀E6c-`DB}YA!Ζ 4Mh%ʭ`5x#8.TAU9C@eGBtDdTQDxj%d^NPsDPB>Do-H\L1M4:bBI_Bz~ك4qAFA1&BY?hG).= LfUPVԩ@~cYf EAzaR߅kg~jeUITT>dZśep)(jJ26` -QCyƴ@)kABVPFt.5jZѾCb lQN9d^Йi^THP%`%g~ιgTtQG5LAV <\LPen={0n@<u{FXk Ӌ$IiD\ 7%=X؅)P.ϳL/TGDqP4px܉=&XL[ψ[~9k9{9s>ͷΛOF'`wO@Fk#+Yg6PJ U_׻{=/ӻ@@nW4އe-qcgʗ  ]7>,p~[:pTA\hK8j&b8 6/|%HS( 8#@e#R 2 7A i¾@ۍJļF SX I$ bFa-yh=Ƈ!b'(5n|n2a5Cbp `#rV ¨ "h@xɍ1cE8(r &3P3aX-) f!E `hʜpE+MD7N @*V)ORƌ;6wu@^@*q0ExfhX#c@Es#T1m2`/.c kf&5C M/WdP0A[P呣[C` 4&o*:{H,Ә`O* 0oǁMH5!4d8 ek*a~cRUA&%S>כEĥadzmeO6əI*=NP*$ Wȧ_@*Bfz$CbTc YВ-m'WV{k Wbh啲+#I#v3$Z~;ɉZkSSA8I7*"jך5Llˢ¶)q.F46.Wd1 aրc 8HOTm@#0Ӛ̖rwMMUI%̿K)R׾I~e˔0YrG 2  B[\1Pa^x6qUǺzl㮎R$&HZw5;Ilx4kYě͙'t`Wټ.yVKQ*g )A6/<&`Kf"+_7jÍKVvkϝ-U(zX$47@CJIwUhlIk[f3yΤEcO~uVBP )ڴEf3y ֶf`ݶi|#S$^\m{w-8!E7ɯdou{̧㶄PϙRBʱwm/&޷uG!C:") cn&>59D>g|MDFp}گMG4v| ܐLHpNYU:zK*BQף'YgC_!zG?C=' Ųިv 4Z(,E}#}ܢ Λ4}ѢmAo+¸!X&}z1Ug/ߓ>ؽ|Ŗ?P?())&׬C {QTO{ID퇧.Ǫ $㧈R4;ўⶎ}'5W9د[%}]ٮ D˓TsHT@DJPM _ ȌhpF@5`gEVxDŽIi8XYvL@* 5LxC`EzXOPZLte (!PGXV`iR ژHY!e=F!CDOXʟ S8uTT𔡒EW|tET$YZ!E"Ѕ]8a_XS1 >[rbt j+>k񠕁rPs8x vpt|Oty=z{1J}ǒJǓI>]-,bD3m; @@t8 #|Qʱǔ$@DL؊?2 S ,̙|G> 6*Z[:Cccbo@6zd<"H/FD  Ĭ 6: N.̬ M(ܮT{JM   rh$9cנulX܍0o J%@1`$eGJ̇F1a\LƄxRLH  [RL˼LR 0Vé%b.fbr%QelJQV:fiJdX\ *A%XyF@ezTGX=kQayԝ$AǙ&q3RTm~d,a|q-gD|=*pF+vgk]\0@Y"Qe'S榩'l$XdgS~'l@8A@bIqjl%k6 beR$,,*RQ5 q>ȞAVj\.bd}BMlcBَ8U ޞ\iƷTi -/VdGoΌ.phU\jL*'MAD@@S  *MĦݶ(%r'/m{  Ih%[ +K܅`@d5@X-@4 t ) (1>/FХo` GrOE[^@@~rH^_o0/i")#{n ]2D؜- .Ad@ X-2ED (27LdImZcKZ/0'x.pV rp 0173 hi9;w'~W)H,^t^JxjX{UPb*tD @ H0`@ \`@Æ F8bE1f ŽA9dG'QT fHpᣀ6 \ȒgO,YhQ&$<`iSOI2hjO/T& ;V#T ",YoƍȀ']pNtV&͛sm{ʠC&Y] ~ٵ4И3 `z$XYY *,uT à T{ypg[ -oUI#w<2f͛zFhj‚ A|FB T 蠚zk/J@l9lpʣi@jZOBC i@NAó@ VH!кiAy0 #;P#%7KDHtKE.#2ম2$"NKpCL,! J`SNKJkIJ``  rT제2P(*mt%&19.t44 3$OJ SRb(:DmR3V,)JhUՓ N&tcg'"iK4KOhru[GV%<*Ua"&qP- *X*r%HȌ-RDإSꥂZA$4:taQ7(WRWtC-x?.Ik9|C┬ 0(DҸa/Mᇣqt|6z%ߕ$St{Y+2ˈ((`7J2A+*o\ b 0oH& 5az#@W]d)xsh.ןh@n+=:sh$t͊|6sT%em/)j@ǔFk*CެvCb`A+#( 4VT`L g+9ȅlrq5`VGĈ R.y 5&f  z,IEh5"`H v%+\ u &NL1bC6E 0јF5mt6btSQeG*FhK",jdy榈0XN!/qId.l`SMi`I£r9e 3{chd ,bM᱙qvtjmF{cTaz/2ÑD%mh;>ҦZ= Ḱ ~|7PQ7 yR?ȯiUfOb2u5B+DO$:Hcڸ3VBPBb>mI'RƛFfu A:£NB)VB!bU"$"<0/2j5M9` kKʤ*(%U 9`EmP6\(0)`#2KٯF,S@$,'L{n8HF2(Z8 A! lvVa +-ư"^|oYCCI%HQ-09.:y/%'7$0 "30 *2 {1|1HK$  }(8| Mpm! .r h" $u8Bqj.V4bObHlIn&W"'p1tpx%u@!ON @L,d&݂I`|#"B#!`~QBޫ4/9xe˾ ,ӽ f 0S1q[,ˌ*59$'RTb8(vDl'@d^B历&T!&@G `0P@,#@E8s&n8#b)Dv!"<-` j!-/D,Td$$ 2umTU *$ո+K_5bKXdžGuRmb@HZLf6t|AJq1xcNWFuFtO= L%r G6NI$o !>~%+Z9%s| &b:R2 ,<}W@E;<0)>jw>CC+*Z,@IRPcFͼO To%\1X#6dk{P^$&o`|u׻o8M $, x_~Aj 7@Zxdp{$Ga^ana~Aƒ&_ߥwB.r'RObWG?B4wXIJf$`HB ASKv'd$ԥUeYѐ93mfn6" q fE4WpypVfolq>JIWJ4I(r誄-[ޕb: ЧnwD2F׬*:Rh*0%jOc$&C*XͦmU)ܾ['HYd[o.^#&f/XuW &if ՐU@%[\Y C.5r/;@ w`%г- g1 l,A!3<5ՙ̫JJq);O-{k]'"t= uݎF7ֆq e7ƹ)Muw <y'~`/~AfrTl^h=;V82%zpY=w"ΐ1}Z^XkCʐye+ot) 0j!B*;H*f>'Z-~9Vr=GsN3@L9dܧ,Ucdf6\O,/nK! ⰺʴ0/ܡwXb䆕!ڮC !,bD}#阺&ʂ!hE)J~^22;_EO6A !5@ze׫b :Z'wV8&x@ F, 0M-,ЂOwG? J*0w3Yb{,ǓףXyrP8 j| 7x0?t ]##_Z(s'2h}*4 @x)mcEɄf4SA1$y{C™f,#*\2诃Y`P0-RaUXVB>9pIBV-9`3f"1U# `$HW,kQrn<¶Zux Q ]2 A_/c &f-W{ uc|SsW Xa_ռ3u ';N8FYC?|5by.)07 /?}Rx`B4=M(!0ۋAmf*ڍZs8V 3ڃybT ^=B-2W/c+GRQt_HJWFo[nX,/?<уbh~BCa6vmJ=|t'c&Y")a)LfqcuuoE!UQ@Rb{5&[7V≟v})z:xq!IAKVA%2*(%KJftesR"~(rΑV:S𲅡Hh-(7m'T)qiϢ48B}}u'a2KH}{CBCceQ;TA^F^(u#SS PoWgDUq:M8@Q8VYÍБ^WkB|X,iT(a;)ΈH ~c0Rq82ka".)1NXjuPf9bLb"8# @W&n(o0LyNeD~u"e# 2 @U@xҖY')B`bxHQ;!^j3+8Kyj\ Z6HJFKKBRQ30 Qql) (hLwyk03=wU4'{F?Qxu)XA62џ#AM9Iߩn&pj5:ꢠx=2Qq  I52j;*(N!p$Z#<$$FLõ2gM JnK|{A,S#v:z5h ؝6Cj>#>'IIhyt싆[&Zl,K𖱔Z #S8\7C%jܾ4VOhM:*?ċR92!{a%9N1}HTn>[GoDyBM !f4yrhHz! F9-{{BAz{/oTGC`K;m|9!4ёkCs O0?AExNNp%WD17"sy,ṒGD&$ъ*;SO "h|DH(c}˲ LJQ]&89"A#JSiLԜ4ZjT:.C4W UrQc##N6N{̥>aͿC,MiL$,K%F%!9JL\^ cLyfAS ˄P&(zzD2q9ʼ5]73bW)93TCӻI nDn1{غGEd&%}ςE$+Pђ8x2f}Hx1G1\M-%{i%{:} &$2K/؝ݵ&e 9C .!~,Gi%d$}hQHJ3D;ȅhڸ=r9|ncz̽Ν ۤ[Y'% ;q:f{=P^,i[H7{ ъVM#r!]59}^}WMq)B %Y_>=xm(H mXrTKq{#H(KK‘Nz*{|N>>Nݐ%]*|dEMn,Q qqU5J%K'Rrrc^2Y/7L<, (S`HEhj~G݀Fψs==zQ-\X ~Qt#z.ԇڦy;>˗iʙ!::~&NBSxN $XkD. OZ~<U![A#!d3u%ݫnu !JꕎK2:d%ˤIsm7yLI5BG#Ѡ{.n$;}rba,s3(BYMi* _|w1$&);4/2(^X3 R*Ǟcų^l,2rY{aMw6| rm=SKo`/=gЁaZ'k?m_.?btߋ.]¶; [WMH!'Nq5sgs<2jU c,#֗E;:8$ZF2ǿ+M8-ſdoɟ?1-8HQL+o1PA .@%N0!E16PF! Ȑ`J1eΤYMܙ'H edA-.eO3 0(BO,Zha:H 連LծQ0 mBqS:0{#giM@Ii.p[} }G Kiz9As K$+HBK kb DS&:Ěj޺ikCs?xq0+ 0mCX4'*\+'% c(K JPZ*'ӓK$@S|HO#wq#|r+r'O\;4#&s%24:ẁ%|%\"r xmtc:o4;C ۟,p\hF=*Y*|op2:T%A%zo3|M2&jD.E$<1m߁ϋZTJh~]L91`kx F e*,$!XG& YruFZ3Iw"!k ɀP.оp1>/^%VM,$(J1 ATAąU+P r'pJAZ(#HN7f=q*lɣX` $&!n5lXyc'VdKrҘBF EYZ\wQhJ4q8iL4.4z,KP2Tڪ:l$ NVP4~²TB "}|6?R[Eg~x8&F&;*Ƙ, 0Дj,ҠA^6{@ڙB-Ӭrd7}3,DŽ@YDT^g~<:_.1Y2Y'\ *Q:b8 @Z Lű43[cRSNju``zeoB % 7:`3"+@,@2s$ T( L`3pC:qA` 3BSkBi aI)?SArAC%&œCi*?̹;|<đI(p ۋ$X+(O—X -.XlCX!FT X ŔEG*E8;٨E_\!F81 pAܩdP7cTvL38p lmL cFik) c2qFUێ k:ё[Av>< ?HH(;}HQĨiGLA{IDda ÈɉpPHy;c HI+ZɖGkɒ (“n<6(K51>c!Ǔ9il/̒\ʩ <ʷ!|Jq  ųo.}t@iMbոH$qZ,kK#L{ˊK6tK0Y(VL+o+S1C+ő BtH?r r>MHt ,8,),K3[N 5p.q2 !d) :ԑ4;ΖԞpN0G`JOHܝdLBΪ@/Y 2Eđ NȁPL:3;}) +G tm;2a˙p 11 8ɨ'5#M'Ļ S$<%"26%X1w 'Q銣Xpo+eR $tӛ0S\ỳ )L̳1TTӠ,THT4KmTG}TlD0##γR 0X k"9SKY ZMorW=Z gZ2U⠩ SqXW׉QWUz#y|T)WSQ: v ™R̙U]M2ݦFXV`-kQXNZM DCZИn9#PyKX+qD"RLa؈aMl`p):^ţŧ$ib!^%G,U7ڭ,ϰLc;c"q+ָ 8f s_C+=#<H.?66ޕG'U;&i\dL~UNVdSZS7(ӉeR^.(ig,((YLɔVViR3fBqixjb [B>LtLْvpj{i)G\"4F%M,k> i"RN*s 궦q.^vk$k_]^hj^l3cfl0J)l=L\;;Մln/ɾlfˆVi8Qnmd"m>v~>j,m;힡VW;mc n瞡vJVYb*n*o0H.[Dn45)jn~X1串AJ nۀ*nUNox>pjJYpJw?goHN>ap=G mA?vhAv?k ::qdh"q%7Yq%*6۠"W`,(r#N2 +s}0,]4s:ϥ a: (4 'o1~s ߼U=_t6ǎw < \F\xEVX᷆wzG4p7kzω{|sHYU'{77גM{+Щnݱ{ |<@ϣv =K 1fs|䥆`|͗9tȟJLO}ףѷkpȣ_}}xư}}@8^KVV~|MĺywB$˯~ ~RN:hPO(9=&ww|lࠧy%& p "Lp!ÆB(q"Ŋ0`#? )r$ɒ&#:X#˖._Œ)s&͚6or\P#F l !F"Mt)ӦNB 1JRbͪU^9~)v,ٲf[UlǕ+w.ݺvrZޖx\P׾l#N|8ۅ<_,y2ʖ/+%L̞?t `sX`3d`Z1֮WM6Wжoέ{h҆ ]QA{x^CϮ};wfXzg.O<6< E5]PuL`lxG}0m6]NCu(#]a[a ՜3]h7ct5bq(+x,8mSR9WbMdJ'GkASP }2ϺkR[O^=8-M ୵jzHo` ^*XjKFU* P{ʰtfKsܱKOt+'+O^̲3\͸i1;@7CE3ݴOC=41X[WcM<c]zSgݶoVY w㝷\岅FzM37=sS^Yo^޹?mK" 駣.zDϦN՗4Y~ B5WE˗Z6 m-4ݞ]_ؓ&3~@;eigenbase-farrago-0.9.0/doc/design/FennelTupleStreams.gif0000444000175000017500000001761111173714170023250 0ustar drazzibdrazzibGIF89a,ڋ޼H扦ʶ L ĢL*̦ JԪjܮ N (8HXhx)9IYiy IZj5:z 듺{2 "F/]fyX![&c)\:Xe&XbPJTv3$Qilh׬oizyY'9蝅hPJ( Y]i@X ~jrʨvj :( &JO lXW +{", k5 % ؃,VbD&wq0;.exxzfI^^M~e,v%l«`HbmŅI_9']q`襓:r{  ~Eh5 R\1`lAAls쩛N3z)#X<;. #/-3%m4 4*, -ZA HM%B ʹeӷvځ:t[@Սw4Q9~s7MлSq 0kB.d8x_|߄ե6jEr~LP?z0c> =;~֛h%,^* 29m/an?T8>Tzej C#h!8i&ص BO a v‰J]alȁp c,Bd 0!>S´A)+(T|Wi9jQ P`T3}RӰ=,jjUbe6ɺ]M VUpŪYـV*& +c3!o|M,խ:6a- lx,E? ڸ[g׈Ԯch\Y!`VEحkYV6k mi;B4enc ]:8.gU,fWmkm[kXVX7n{!]Y]o~ ߣ&w `7׭-pz{`>& k-HxҔf43Kk"f!&#3sy9tY((~; o >} ]CM?lKXۘ% GTܿcN?m?A\4umoG2 ~Oww;}jCp"oQ0w}x2}mf9oICW6'6qMuzrҁw$fl $Ƃ7"2G0EL'n"n}6vj"q!Hh0~ö|7Ĉaǀ]($h"B1yBpR|1u=m{Bi"y|W֊61-o w#WьkUʘw(8Hx{hv|XoX_Swt?qGz(xX`רh'YjXv i{sxփSX'x=A|O3n#l2M3'w/G-Ik7# Zztu)e( 1#%9}(ȇwqׇ$Ė ÈDxm~'.V !cK.n3p)QHy~+FI^|9f.B J!=HpX(ꖋEhn|PiwymiG@A2 Xsb+1.%陮ț1 Es9IYɃXM8|(LH`{xeS%Y)wѩ9MytÙらykiƚYg+ExK (ù}ّuI"lɅ ΆJǘqꡎh''!܉ɐP(ע?"*95j1 ʣч%:; X7uB HA3)H@Ƥ$CGuDTt7~qzIg*DWOa.]zhIx. zڣpFDTGxm钨wv9Zjv5D› |Z8zC I]ؔʄzyk%Yv[ëx1Yl*o؂0zZTV $xl7N2 :☵JNDz0'ʦ*ɴT Ii:z*EZZz2 M~Ek*"5{Y :d@uʱ  D#k%('+sߤ 93/.(k犳9г9KA˳HzFk CSK˴Q+ SLUkoD;[ X[/ Leg[dk۵O o{qKsK\{I x~dY {&J 붉+Ft+{CJfc{rzk۹kD ;ZE뺟h;k{{˸u(aۺǻ۶˼K˹iW { ë+K˾ޛ+Ke;^{ͻ\竼 Le{,ULh'Dd,;[&l\T,l:qk[ʥ\bïa=ڠ؂;LW+|g/f'FA'H)WMȍO ŭìž9X~ᕰy]|_PhqHYjlilj鞡%ilpA68gX9Ás,ìŽ|;LbHq<`ɡɠ^s4ʒLæȨʩʬqʘ,klk˷ß¿,F\vX(7 ǯŹzDC.C,ziړ:H Q.sʬdž͢Z#R9 ̖pj1|Lˣ: ǟفd<7Z'ͣ4ɕڬUH}hӬmIʂΒ*{'9I&9͌ }; _ԆGHW OPSWXP]m_ -LP}g\fLWq]b߁N},~ݾ{]=}mT@؇Q Pl,_m`\,q[mm\hЅ)pV^yW4ͯjne6ٶևwC> ʲ~]즎z-,-`=ʮRWBN(\&vyZ׼h:J Ϲ|6x΁hzW)$Zr90(9W>D fW2vWYlB/,o=C $^IT,p'p~I{'<N{:J^ M?6">=k9&3ǕIiA-|<_ ·[윫IW7ݖH↟>FߤQ[VR:|o}QRC;|Ę-T5YTSY:PV '><8_P/~^[[DJS@R艍ժ+)V>fsJDN[>(u@<@8%ͮO/`aV{q wPIOT]k+X>}ANW4sWDI'l>manA(tuxr,eNc_Y"ǵYOe7Q [6]AcJ3Nޥk ݚw)4nR(N^a*xǣ=A,pJZ4 X~<@Xa{M}gyD t(,CA9bFu.jJETtEha6FĕwݘI킛9ƍ7x.Rt ;lcI8A_yy+ѧŦsTr҃*%lNܦqo:=#;YZ'ZyྡG>zuק;38)ע=|woyByw<} t]O&~+LlP- p$4C> ;A! mD)6DQ8]= T\qDZlFGGMHhL2?R'#I2J J S1L)͞ZP"ˬ-usOwGAs PQQR?rEEUUY"n>wN]^/ڷ+#ɤ|q)Ԅ|%3C#tHf}z쟊#ƖWܤͶhm5›8ݑ-J+w.eY$6_YUl>J݉|֤o)UnZh5:H񬦚qaN J-+#-춻Mq~#Wt FfQwd  `j'7p#]ZO=`Jͮ*)w̝]Ӏh쥺{`&S3XcZ؅2  lhXx ^[AyC *s"BRL (C P^!oCC<$"x &хGč2QS<B-nNPbdE8,Qe4c83#ZX4/QW܅6}/2<5,‘17qu#Hnޜ&*yK[ҤwF.j327ʝ]W up \ GGS3lSR滬l*QٿSMsTZ`ΏݜONf`|x 6I<^lCBm͛\1+Ǽyk yKv he߲yҞ RPF0K6 +?:EdGW$Ts GMRGe-њV4T5[.Uu](}&YXu5aZX.=Ulc!Y>V,$){YntgAK̆hMZV ukZΖ@jmq[%V^y[7%q;&]q]Ɠcӵu'n׺w]%y_k^״e{?^ײ}k_Wkoo_^!C6mN` P1'fR{+%2X7piaYB y$yU(Z6qfD,,3nE@5ì2~MJld"?Leιd6/^| Zsfܾ;K[8ĺ 89f\ʓ5xmSφLnxF. q/dfMx쳔]6hQG\TY⬫<6fM=ܩZgQaw^K/lt};lr]c;;c8mjgtn7]rE!o^Mզ+^Z~ D{ 'mR;<p<lq`|OfEw'oq7僔8g^79w4ye^tCg/|P-($w}M_mwwݫ;eigenbase-farrago-0.9.0/doc/design/sqlmed.html0000444000175000017500000002353011173714170021151 0ustar drazzibdrazzib Farrago SQL/MED Support

Farrago SQL/MED Support

This document describes Farrago support for SQL/MED (Management of External Data), the portion of the SQL:1999 standard which governs access to foreign data (both relational and non-relational) hosted in other servers.

Overview

SQL/MED defines several very independent interfaces:
  • An SQL DDL interface for defining access to foreign data.
  • An underlying programming-language-neutral service provider interface to be implemented by foreign data wrappers (drivers for various kinds of data). This interface is wide, complex, and non-trivial to implement. For example, in order to support metadata import, an implementation must support SQL queries against the standard INFORMATION_SCHEMA (probably not something the developer of a flat-file driver wants to deal with).
  • Datalink interfaces (not covered in this document).
Farrago supports the standard DDL interface but not (currently) the standard foreign data wrapper service provider interface. Instead, Farrago defines a somewhat simpler non-standard service provider interface together with some prepackaged implementations:
  • FTRS: for access to data stored by Fennel in transactional row format. This is not really foreign data, but is represented as such for architectural uniformity. A normal CREATE TABLE statement uses this implicitly. The CREATE TABLE statement has been extended to allow creation of other types of table storage (e.g. FCS for a hypothetical Fennel column-store format).
  • JDBC: for access to data stored in foreign SQL databases.
  • MDR: for access to metadata stored in an MDR repository (including Farrago's own system catalog).
  • MOCK: for testing or dummy tables.
Eventually, if standard SQL/MED foreign data wrapper drivers become popular, Farrago will either provide a bridge for them as another implementation of its non-standard interface, or will make its own non-standard interface obsolete. The standard DDL will remain unchanged in any event.

Foreign Data Wrapper Definition

The standard SQL/MED DDL statement to install a driver is CREATE FOREIGN DATA WRAPPER:

CREATE FOREIGN DATA WRAPPER foreign-data-wrapper-name
[ LIBRARY 'libraryName' ]
LANGUAGE language-name
[ OPTIONS ( opt-name1 'opt-value1' [, opt-name2 'opt-value2' ... ] ) ]
Initially, Farrago requires the LANGUAGE to be JAVA. The LIBRARY name specifies the path to a JAR containing the wrapper implementation. Here's a fictitious example for a foreign data wrapper capable of fetching XML files via TCP/IP:

CREATE FOREIGN DATA WRAPPER xml_tcpip
LIBRARY '/home/jvs/wrappers/FarragoXmlSourceReader.jar'
LANGUAGE JAVA
OPTIONS ( protocol 'TCP/IP' )
According to the standard, foreign data wrappers are catalog objects. In Farrago, they are implicitly created under the SYS_BOOT catalog (and so must have top-level unique names).

As an extension, Farrago also allows a foreign data wrapper to be specified as the fully-qualified name of a class available on the server's classpath (instead of in a particular JAR file):


CREATE FOREIGN DATA WRAPPER xml_
LIBRARY 'class com.yoyodyne.farrago.plugin.xml.FarragoXmlDataWrapper'
LANGUAGE JAVA
OPTIONS ( protocol 'TCP/IP' )

Foreign Server Definition

Once a foreign data wrapper has been installed, it can be bound to data provided by a particular server with the CREATE SERVER statement:

CREATE SERVER foreign-server-name
[ TYPE 'server-type' ]
[ VERSION 'server-version' ]
FOREIGN DATA WRAPPER foreign-data-wrapper-name
[ OPTIONS ( ... ) ]
Example using the previously defined wrapper:

CREATE SERVER movie_catalog
TYPE 'ANY'
VERSION '1.1'
FOREIGN DATA WRAPPER xml_tcpip
OPTIONS ( url 'http://www.movie-fun-facts.org' )
Any type of web server would be allowed, but it would have to support HTTP version 1.1 (and the wrapper would expect HTTP features to work accordingly). As with foreign data wrappers, foreign servers are created under the SYS_BOOT catalog, and their names must not conflict with any other server (or catalog) in the system.

According to the SQL/MED standard, defining a foreign server does not make its data accessible (the CREATE FOREIGN TABLE or IMPORT FOREIGN SCHEMA statements described later are required first). However, Farrago introduces a non-standard mechanism for direct access. Each foreign server defined implies a corresponding top-level virtual catalog. These catalogs are virtual in the sense that no local metadata is stored for them (and no INFORMATION_SCHEMA is defined). Instead, metadata is acquired on-the-fly during query processing. For example, after the above CREATE SERVER example, the following query might be legal:


SELECT DISTINCT r.name
FROM movie_catalog.review_facts.reviewers r,
     movie_catalog.movie_facts.actors a
WHERE r.name=a.name
This queries the names of all actors who have the same names as movie reviewers. The FarragoXmlSourceReader wrapper implementation might map each subdirectory under the root URL to a schema, and xml files in those subdirectories to tables. However, a metadata query like

SELECT * 
FROM movie_catalog.information_schema.table
would fail unless the FarragoXmlSourceReader implementation happened to support the INFORMATION_SCHEMA (unlikely in this case, but more likely for a JDBC foreign data wrapper).

Virtual catalogs are read-only (it is not possible to create new schemas, tables, or other objects under them).

Foreign Table Definition

In order for metadata about a foreign table to be stored in the LOCALDB catalog, a CREATE FOREIGN TABLE statement is required:

CREATE FOREIGN TABLE table-name
SERVER foreign-server-name
[ ( basic-column-definition1 [, basic-column-definition2 ... ] ) ]
[ OPTIONS ( ... ) ]

A basic-column-definition consists of a name, a datatype, and (optionally) a column-level OPTIONS clause.

For example:


CREATE FOREIGN TABLE movie_schema.reviewers
SERVER movie_catalog
OPTIONS ( directory 'review_facts', file 'reviewers.xml' )
Here, the foreign XML file previously referenced implicitly (via SQL identifiers in the virtual catalog) is now referenced explicitly (via wrapper-specific options). The local schema MOVIE_SCHEMA must already exist under the LOCALDB catalog. Since column definitions were omitted, the wrapper must be capable of deriving these automatically from the XML file contents. Now, we can issue a query like

SELECT * 
FROM movie_schema.reviewers
or a metadata query like

SELECT column_name
FROM localhost.information_schema
WHERE table_schema = 'MOVIE_SCHEMA' 
AND table_name = 'REVIEWERS'

Foreign Schema Import

In order to import metadata for a number of tables at once, SQL/MED provides the IMPORT FOREIGN SCHEMA statement (available in version 0.6):

IMPORT FOREIGN SCHEMA foreign-schema-name
[ 
 { LIMIT TO | EXCEPT }
 { ( table1 [, table2 ... ] ) | TABLE_NAME LIKE 'pattern' }
]
FROM SERVER foreign-server-name
INTO local-schema-name
The LIMIT TO clause restricts the import to an explicit list of table names or those matching a LIKE pattern. If a list is provided, all of the named tables must exist on the foreign server or the import will fail. Conversely, the EXCEPT clause imports everything except those named in the list or matching the LIKE pattern. Note that the LIKE pattern is a non-standard extension.

For the running example (this imports only table names starting with R):


IMPORT FOREIGN SCHEMA movie_facts
LIMIT TO TABLE_NAME LIKE 'R%'
FROM SERVER movie_catalog
INTO localhost.movie_schema
Note that as with CREATE FOREIGN TABLE, local schema MOVIE_SCHEMA must already exist before the IMPORT statement is executed.

Additional DDL

SQL/MED defines statements such as DROP/ALTER for foreign data wrappers, servers, and tables. It also defines additional DDL for controlling mapping of users and routines. For the details, consult the standard. Currently, Farrago only supports CREATE/DROP.

Java Interfaces

The interfaces which must be implemented in order to write a new foreign data wrapper are defined in package net.sf.farrago.namespace. Abstract bases in package net.sf.farrago.namespace.impl ease the construction of new wrappers. It is currently a fairly difficult task to develop a new wrapper; eventually a stripped down service provider interface may be defined to make it easier to wrap simple data. Another option for some types of data is to acquire a JDBC driver and use Farrago's JDBC wrapper.

Repository Model

Since CWM does not cover any SQL/MED metadata, the repository model for foreign data is defined in the Farrago extension model (FEM). Each foreign table has an association with a corresponding foreign server, together with options specified when it was created. Catalog initialization also creates a representation for the local server, to which tables stored locally are attached. Catalog initialization creates virtual catalogs for the local MDR repository metadata (using MedMdrForeignDataWrapper). Below is a UML structure diagram for the SQL/MED model:
(Apologies for that interloper in the background!)
The two associations (WrapperAccessesServer and ServerStoresTable) also imply dependencies for DROP RESTRICT/CASCADE. eigenbase-farrago-0.9.0/doc/status.html0000444000175000017500000003652311173714170017744 0ustar drazzibdrazzib Farrago Status Page

What's Working Already?

Here's a laundry list of SQL features which are already working in Farrago as of release 0.7. If a sub-feature isn't mentioned (e.g. CHECK clause in CREATE TABLE), it isn't available yet. Everything is supposed to work according to the SQL standard, so if something doesn't, that's either a bug or an incomplete feature. Which standard? Normal procedure is to consult the SQL:2003 standard and cross-check it with SQL-92 and SQL:1999 to see if there are any incompatibilities.

DDL

  • All identifiers may be up to 128 characters. Identifiers may be quoted (with case-sensitivity) or unquoted (with implicit uppercasing before both storage and lookup). The compound identifier "catalog_name"."schema_name"."object_name" fully qualifies a schema element.
  • SET CATALOG: the system currently starts out with several catalogs predefined (SYS_BOOT, SYS_MOF, SYS_CWM, SYS_FEM, and LOCALDB). Additional catalogs can be created implicitly via the SQL/MED CREATE SERVER command. The SYS_BOOT catalog contains internal tables for metadata storage, along with things like views for implementing JDBC metadata. The SYS_MOF catalog is a virtual catalog exposing the highest-level metamodel. The SYS_CWM catalog is a virtual catalog exposing the contents of the CWM-based repository. SYS_FEM is similar, but for Farrago extensions to CWM. The LOCALDB catalog stores user metadata about both local and foreign tables. The default catalog starts out as LOCALDB; SET CATALOG can be used to change this per-session.
  • SET SCHEMA: user schemas are created in the LOCALDB catalog. SET SCHEMA can be used to change the default schema within the current catalog. The SYS_CWM catalog defines one schema per CWM package (e.g. "Core", "Relational", or "KeysIndexes"); the tables in the CWM schemas correspond to classes (e.g. schema SYS_CWM."Core" contains "ModelElement" and "Feature"; schema SYS_CWM."Relational" contains "Table" and "View"). Likewise for SYS_FEM.
  • CREATE SCHEMA: a schema can be created by itself, or together with all of its contents in the same statement. The AUTHORIZATION clause is currently parsed but ignored. The PATH clause is supported for UDR/UDT lookup.
  • CREATE TABLE: for the default row-store implementation, every table must have a primary key. Supported column datatypes are BOOLEAN, TINYINT, SMALLINT, INTEGER, BIGINT, DECIMAL (alias NUMERIC), REAL, DOUBLE (alias DOUBLE PRECISION), VARCHAR (alias CHARACTER VARYING), VARBINARY, CHAR (alias CHARACTER), BINARY, DATE, TIME, TIMESTAMP, and user-defined type. Decimal precision is limited to 19 digits. Time precision is currently limited to seconds, but will eventually be enhanced to microseconds (which should be the default for TIMESTAMP according to the SQL standard). Timezones are not yet supported. Support for standard multisets and time intervals is currently under development. Autoincrement columns are supported.
  • NOT NULL: can be specified explicitly on any column; is also implied for columns which participate in the table's primary key (or clustered index for row-store tables).
  • DEFAULT: can be specified for any column; otherwise default value is NULL. Currently, default values can only be literals of the appropriate datatype (not arbitrary expressions).
  • PRIMARY KEY/UNIQUE: constraints can be specified at either the column level or the table level. Constraints can be named, and are enforced via implicitly created indexes.
  • CREATE CLUSTERED INDEX: if specified, this must be at the end of the CREATE TABLE statement, not in a separate statement. Example:
    
    create table t(i int not null primary key,j int not null,k int)
    create clustered index t_x on t(j);
    create index t_y on t(k);
    
    If not specified, the primary key is used implicitly for clustering. For the default row-store, every table has exactly one clustered index.
  • CREATE INDEX: unclustered indexes can be created either at the end of the table definition or in separate statements. Indexes are considered to be schema elements but are always created in the same schema as their containing table.
  • CREATE GLOBAL TEMPORARY TABLE: supports ON COMMIT {PRESERVE|DELETE} [ROWS] option. Note that the "GLOBAL TEMPORARY" name in the standard is confusing: this is really an instantiate-on-reference session-local temporary table with a permanent shared metadata definition in the catalog. Any indexes on a temporary table must be specified together with the CREATE TABLE statement; indexes may not be subsequently added or dropped (if you need that, drop and recreate the table definition). Beyond that, temporary tables support the same features as permanent tables (constraints, defaults, etc.). However, see the "What's Broken" section below for some known issues.
  • CREATE VIEW: all views are currently read-only.
  • SQL/MED support. CREATE/DROP FOREIGN DATA WRAPPER, CREATE/DROP SERVER, and CREATE/DROP FOREIGN TABLE are working, along with IMPORT FOREIGN SCHEMA. Implementations for JDBC, flatfiles and MDR are available (the MDR implementation is already being used for exposing the catalog contents via SQL). The system starts out with foreign data wrappers SYS_MDR, SYS_MOCK_FOREIGN, SYS_JDBC, and SYS_FILE_WRAPPER predefined. Foreign data server SYS_MOCK_FOREIGN_DATA_SERVER and HSQLDB_DEMO can be used for test purposes.
  • Pluggable storage engine support via CREATE/DROP LOCAL DATA WRAPPER. The system starts out with local data wrappers SYS_FTRS (row-store) and SYS_COLUMN_STORE (LucidDB column-store), as well as SYS_MOCK. A corresponding local data server (SYS_FTRS_DATA_SERVER, SYS_COLUMN_STORE_DATA_SERVER, or SYS_MOCK_DATA_SERVER) can be specified in the SERVER clause for CREATE TABLE when creating a local table (default is SYS_FTRS_DATA_SERVER for vanilla Farrago session personality).
  • CREATE FUNCTION/PROCEDURE: supports functions with SQL-defined bodies consisting of a single RETURN statement, and Java-defined external functions and procedures with IN parameters only. For external functions, parameters must be of builtin type. Procedure result sets are not supported, but see the UDX spec for user-defined transformation functions which take cursors as input and return tables as output. External routines may call back into JDBC via standard jdbc:default:connection.
  • CREATE TYPE/CONSTRUCTOR/ORDERING: supports SQL-defined types (both structured and distinct, but not domains and not SQL/JRT). Neither type inheritance nor typed tables are supported. Constructor methods may only consist of a list of SET attribute statements followed by RETURN SELF. Observers are supported but mutators are not. User-defined casts and transformations are not supported, but user-defined orderings are. Directly querying distinct type values via JDBC is supported; this is currently unreliable for structured types.
  • CALL SQLJ.INSTALL_JAR/REMOVE_JAR: standard system-defined procedures for jar management. Also supported are non-standard CREATE/DROP JAR statements; these are equivalent and used internally to implement the standard SQLJ procedures. Deployment descriptors and jar paths are not yet supported.
  • SET PATH: defines the lookup scope for user-defined routine and type references.
  • DROP: both RESTRICT and CASCADE are supported where relevant.
  • DROP INDEX: only unclustered indexes may be dropped.
  • TRUNCATE TABLE "tbl": delete all rows from tbl without logging them individually.
  • ALTER TABLE "tbl" REBUILD: physically reorganize table contents, purging deleted entries and rebalancing indexes where supported.
  • ALTER TABLE "tbl" ADD COLUMN: add a new column to an existing table.
  • ANALYZE TABLE "tbl" {ESTIMATE|COMPUTE} STATISTICS FOR { ALL COLUMNS | COLUMNS (a, b, c...) }: collect statistics on stored data distribution for use by the optimizer.
  • ALTER SYSTEM SET "parameterName" = value; change a system parameter (see documentation for all parameters).
  • CHECKPOINT: force an immediate checkpoint.
  • COMMIT: commit current transaction.
  • ROLLBACK: rollback current transaction.
  • SAVEPOINT "x": create a savepoint with name x.
  • ROLLBACK TO SAVEPOINT "x": partially rollback current transaction to savepoint x.
  • ALTER SYSTEM ADD CATALOG JAR and ALTER SESSION IMPLEMENTATION {SET|ADD} JAR: Farrago-specific mechanisms for system extensibility
  • ALTER SYSTEM REPLACE CATALOG: Farrago-specific catalog upgrade mechanism
  • CREATE OR REPLACE [ RENAME TO "new-name" ] is supported for all objects except local tables and indexes. This is a Farrago-specific extension. The command succeeds as long as the replacement definition does not invalidate any dependencies.
  • CREATE ROLE "role-name" [ WITH ADMIN "admin-auth-id" ]
  • CREATE USER "user-name" [ AUTHORIZATION 'auth-string' ] [ DEFAULT {CATALOG|SCHEMA} "default-qualifier" ]: this is a Farrago-specific extension (SQL:2003 stops at role level.)
  • GRANT role/privilege
  • Sample datasets: This is a Farrago-specific extension.

Queries

  • SELECT [DISTINCT] ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY
  • UNION [ALL], INTERSECT, EXCEPT
  • FROM clause may contain tables, views, multi-row VALUES, LEFT/RIGHT/INNER/CROSS JOIN, old-style comma list, nested queries, UDX invocations, and explicit TABLE references.
  • EXPLAIN PLAN [ { EXCLUDING | INCLUDING [ ALL ] } ATTRIBUTES ] [{WITH|WITHOUT} IMPLEMENTATION] [AS XML] FOR query-or-DML-statement; shows optimizer plan. WITHOUT IMPLEMENTATION yields unoptimized abstract relational plan. Default is WITH IMPLEMENTATION, which yields optimized plan with all physical operators. AS XML yields detailed output in element-oriented XML. EXCLUDING ATTRIBUTES shows relational operator names only. INCLUDING ATTRIBUTES is the default. INCLUDING ALL ATTRIBUTES provides additional attributes such as cost.
  • TABLESAMPLE with BERNOULLI and SYSTEM options
  • The LucidDB SQL reference has the most up-to-date list of supported row expressions

DML

  • INSERT
  • UPDATE
  • DELETE
  • MERGE (FTRS support not yet available)
  • CALL

JDBC API

  • prepared statements with dynamic parameters (e.g. select * from emps where name=?)
  • DatabaseMetaData: all except getTablePrivileges, getColumnPrivileges, getBestRowIdentifier, getVersionColumns, getImportedKeys, getExportedKeys, getCrossReference
  • savepoint API
  • autocommit or manual commit (either via API or via SQL)
  • implicit query plan cache

Optimizer

  • hash join/agg and nested loop joins for inner and outer joins
  • cartesian product join (for inner joins and degenerate outer joins)
  • index join (for LEFT, RIGHT, or INNER join; single-column equijoin only)
  • single-column index search; only one index at a time
  • hybrid Java/Fennel plans

Executor

  • Row expressions are implemented via a mix of Java code generation and Fennel calculator programs. In cases where both implementations are available for the same value expression, the optimizer decides (currently always in favor of Fennel; eventually this should be properly costed). System parameter "calcVirtualMachine" governs this behavior (default setting CALCVM_AUTO uses mixed mode; CALCVM_FENNEL forces Fennel only; CALCVM_JAVA forces Java only, used implicitly when Fennel support is not available).
  • Generated Java code is compiled by the Janino compiler (and then possibly to native code JIT).
  • All other execution objects are implemented by Fennel, except for foreign table access (such as MDR or JDBC).
  • Each DML statement runs in its own implicit subtransaction as required by the standard.

Management API

Runtime Modes

  • Embedded engine: everything runs in a single process; JDBC calls go into the engine directly.
  • Client/server: implemented using VJDBC. By default, the server listens for RMI connections on port 5433, and uses multiple dynamically assigned ports for individual RMI objects. This can be controlled via configuration parameters; serverRmiRegistryPort controls the connection port, and serverSingleListenerPort forces all RMI objects to multiplex over a single statically assigned port (default value of -1 means use dynamically assigned ports for this instead).

What's Broken?

Besides the absence of important standard stuff like referential integrity, it's worth mentioning some serious limitations in the features listed above:
  • REVOKE is not yet implemented, and authorization checks are limited to table access only (authorization checks for DDL statements is not yet implemented). No authentication method is implemented yet. There are a number of known security problems in routine invocation, system routine accessibility, and SQL/MED.
  • Type inference is missing for some dynamic parameter contexts.
  • You can specify a CHARACTER SET name on CHAR/VARCHAR columns from only the single-byte character sets known to Java.
  • Bulk load for multi-level trees is implemented internally, but not yet hooked into CREATE INDEX.
  • There's no lock manager in the vanilla Farrago session personality, so concurrency control defaults to dirty read, with the potential for recovery failures due to write-on-write conflicts.
  • Updates to unique keys are not ordered correctly, so spurious uniqueness violations result for a statement like update t set pk=pk+1 (where pk is a primary key). This probably won't be fixed until triggers are implemented.
  • INSERT/UPDATE do not support the explicit DEFAULT keyword.
  • The SET SCHEMA command cannot be used to set a schema in a virtual catalog based on a SQL/MED server (including the predefined SYS_CWM and SYS_FEM catalogs).
  • There are a number of problems with global temporary table support; see FRG-337 and FRG-298.
Feedback on anything inaccurate or missing from these lists is always apppreciated. eigenbase-farrago-0.9.0/unitsql/0000755000175000017500000000000011173714170016456 5ustar drazzibdrazzibeigenbase-farrago-0.9.0/junitSingle0000555000175000017500000001521311173714170017200 0ustar drazzibdrazzib#!/bin/bash # $Id: //open/dev/farrago/junitSingle#22 $ # Farrago is an extensible data management system. # Copyright (C) 2005-2009 The Eigenbase Project # Copyright (C) 2005-2009 SQLstream, Inc. # Copyright (C) 2005-2009 LucidEra, Inc. # Portions Copyright (C) 2003-2009 John V. Sichi # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later Eigenbase-approved version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA function usage { echo "junitSingle [options] TEST [TARGET]" echo echo "Run a single Junit test case," echo "where TEST is:" echo " - the fully-qualified name of a test class" echo " e.g. com.sqlstream.aspen.test.jdbc.Main" echo " Unqualified test classes are assumed to live in package" echo " net.sf.farrago.test, or ${EIGEN_TEST_DEFAULT_PACKAGE} if it" echo " is set." echo " - or the relative path to a SQL test" echo " e.g. unitsql/jdbc/metadata.sql" echo " - or the pseudo-test 'UNITSQL' to run all SQL unit tests" echo " defined by 'fileset.unitsql' in build.xml" echo " - or the pseudo-test 'MTSQL' to run all concurrent SQL tests" echo " defined by 'fileset.concurrentsql' in build.xml" echo echo "and TARGET is a target in build.xml (default 'junit')." echo " Use "junit.client" target to run test through client driver," echo " e.g. ./junitSingle unitsql/jdbc/metadata.sql junit.client" echo echo "Options:" echo " -n no-op " echo " -e echo command before executing it" echo " -g debug test with jswat" echo " -v pass -v flag to ant" echo " --repeat Run the test repeatedly until it fails" echo " --[no]build Whether to compile first. Default is to not compile." echo " --help Print this help" } # Parse flags once=true build=false help=false nope=false echoCmd=false swat=false ANT=ant while [ $# -gt 0 ]; do case "$1" in -n) nope=true; shift ;; -e) echoCmd=true; shift ;; -g) swat=true; shift ;; -v) ANT="ant -v"; shift ;; -repeat|--repeat) once=false; shift ;; --build) build=true; shift ;; --nobuild) build=false; shift ;; --help) help=true; shift ;; *) break esac done if $help; then usage exit 0 fi if [ ! "$1" ]; then echo "Error: specify a .sql or .java filename or a test class name"; usage exit 1 fi test=$1 utarget=$2 if [ ! "$EIGEN_TEST_DEFAULT_PACKAGE" ]; then EIGEN_TEST_DEFAULT_PACKAGE=net.sf.farrago.test fi function chooseTarget { if [ "$utarget" ]; then target="$utarget" else if $swat; then target=jswat.junit else target=junit fi if $build; then target="all $target" else : fi fi } function chooseCommand { chooseTarget if [ -e "$test" -a ${test:0-5} == ".java" ]; then # Interpret the argument as the name of a java source file. # Convert it to the name of a java class. # For example, "src/com/acme/foo/Bar.java" becomes "com.acme.foo.Bar". junit_class=$(awk ' /^package / { p = substr($2,0,length($2)-1); } /^public.* class / { for (i = 1; i <= NF; i++) { if ($i == "class") { c = $(i+1); print p "." c; exit; } } }' "$test") command="$ANT -Djunit.class=$junit_class -Dfileset.unitsql='' $target" elif [ -e "$test" ]; then # Interpret the argument as the name of a script to run # Assume unitsql tests junit_class=net.sf.farrago.test.FarragoSqlTest fileset=fileset.unitsql nullfilesets="-Dfileset.regressionsql='' -Dfileset.concurrentsql='' -Dfileset.unitlurql=''" # if we're running regressionsql tests, use the right class and ant target if [ ${test/*regressionsql*/x} == "x" ]; then if [ "$target" == "jswat.junit" ]; then # REVIEW: it needs a jswat.junit.regressionsql target that sets # the necessary system properties for regressionsql tests. echo "build.xml does not support jswat on regressionsql" exit 1; fi target=regressionWithoutBuild junit_class=net.sf.farrago.test.regression.FarragoSqlRegressionTest fileset=fileset.regressionsql nullfilesets="-Dfileset.unitsql='' -Dfileset.concurrentsql='' -Dfileset.unitlurql=''" elif [ ${test:0-6} == ".mtsql" ]; then if [ "$target" == "jswat.junit" ]; then # REVIEW: it needs a jswat.junit.regressionsql target that sets # the necessary system properties for regressionsql tests. echo "build.xml does not support jswat on regressionsql" exit 1; fi target=regressionWithoutBuild junit_class=net.sf.farrago.test.concurrent.FarragoTestConcurrentTest fileset=fileset.concurrentsql nullfilesets="-Dfileset.unitsql='' -Dfileset.regressionsql='' -Dfileset.unitlurql=''" elif [ ${test:0-6} == ".lurql" ]; then junit_class=net.sf.farrago.test.LurqlQueryTest fileset=fileset.unitlurql nullfilesets="-Dfileset.unitsql='' -Dfileset.regressionsql='' -Dfileset.concurrentsql=''" fi command="$ANT -Djunit.class=$junit_class $nullfilesets -D$fileset=$test $target" else # Interpret the argument as the name of a test case if [ -z `echo $test | grep '\.'` ]; then test=$EIGEN_TEST_DEFAULT_PACKAGE.$test fi nullfilesets="-Dfileset.unitsql='' -Dfileset.regressionsql='' -Dfileset.concurrentsql='' -Dfileset.unitlurql=''" command="$ANT -Djunit.class=$test $nullfilesets $target" fi } chooseCommand if $echoCmd; then echo $command fi if $nope; then exit 0; fi if $once; then $command; else count=1 echo ::: Execution $count started at `date` while $command; do # no sense building more than once if $build; then build=false chooseCommand fi let count++; echo ::: Execution $count started at `date` done echo Failed on execution $count exit 1; fi # End junitSingle eigenbase-farrago-0.9.0/p4fem.xml0000444000175000017500000000140711173714170016514 0ustar drazzibdrazzib eigenbase-farrago-0.9.0/distBuild.sh0000555000175000017500000001544011173714170017243 0ustar drazzibdrazzib#!/bin/bash # $Id: //open/dev/farrago/distBuild.sh#45 $ # Farrago is an extensible data management system. # Copyright (C) 2005-2009 The Eigenbase Project # Copyright (C) 2005-2009 SQLstream, Inc. # Copyright (C) 2005-2009 LucidEra, Inc. # Portions Copyright (C) 2003-2009 John V. Sichi # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later Eigenbase-approved version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA # Script used to create an "installable" Farrago build. # NOTE jvs 13-Mar-2005: We can't use ant to do most of this, because # it has poor support for symlinks and file permissions. usage() { echo "Usage: distBuild.sh [--without-init-build][--with[out]-debug]" } if [ ! -e dist/FarragoRelease.properties ]; then echo "Error: You must create file dist/FarragoRelease.properties first." echo "See dist/ExampleRelease.properties for a template." exit -1 fi # Detect platform cygwin=false case "`uname`" in CYGWIN*) cygwin=true ;; esac if [ $cygwin = "true" ]; then SO_3P_PATTERN="*.dll" SO_PATTERN="*.dll" else SO_3P_PATTERN="lib*.so*" SO_PATTERN=$SO_3P_PATTERN fi #default init_build=true dist_fennel=true remove_debug=true while [ -n "$1" ]; do case $1 in --skip-init-build|--without-init-build) init_build=false;; --with-debug) remove_debug=false;; --without-debug) ;; *) usage; exit -1;; esac shift done if $init_build; then debug_param=--with-debug if $remove_debug; then debug_param=--without-debug fi ./initBuild.sh --with-fennel ${debug_param} else echo "Skip init build" # if fennel was not build, don't include it. if ( grep -q -i '^fennel.disabled=true' initBuild.properties ) ; then dist_fennel=false; else dist_fennel=true; fi fi set -e set -v # set up directories OPEN_DIR=$(cd ..; pwd) FARRAGO_DIR=$OPEN_DIR/farrago DIST_DIR=$FARRAGO_DIR/dist FENNEL_DIR=$OPEN_DIR/fennel THIRDPARTY_DIR=$OPEN_DIR/thirdparty # create staging directory TMP_DIR=$DIST_DIR/tmp rm -rf $TMP_DIR mkdir $TMP_DIR # get help from ant to figure out where to build release image cd $DIST_DIR ant createReleaseDir # derive staging sub-directories RELEASE_DIR=`echo $TMP_DIR/*` LIB_DIR=$RELEASE_DIR/lib PLUGIN_DIR=$RELEASE_DIR/plugin INSTALL_DIR=$RELEASE_DIR/install CATALOG_DIR=$RELEASE_DIR/catalog BIN_DIR=$RELEASE_DIR/bin # create staging sub-directories mkdir $LIB_DIR mkdir $PLUGIN_DIR mkdir $LIB_DIR/mdrlibs mkdir $LIB_DIR/enki mkdir $LIB_DIR/fennel mkdir $INSTALL_DIR mkdir $CATALOG_DIR mkdir $CATALOG_DIR/fennel mkdir $BIN_DIR # copy thirdparty libs cd $THIRDPARTY_DIR cp janino/lib/janino.jar $LIB_DIR cp janino/src/org/codehaus/janino/doc-files/new_bsd_license.txt $LIB_DIR/janino.license.txt cp resgen/lib/eigenbase-resgen.jar $LIB_DIR cp resgen/lib/eigenbase-xom.jar $LIB_DIR cp resgen/COPYING $LIB_DIR/resgen.license.txt cp mdrlibs/* $LIB_DIR/mdrlibs rm -f $LIB_DIR/mdrlibs/uml*.jar rm -f $LIB_DIR/mdrlibs/mdrant.jar cp enki/*.jar enki/*.txt enki/LICENSE $LIB_DIR/enki rm -f $LIB_DIR/enki/eigenbase-enki-*-doc.jar rm -f $LIB_DIR/enki/enki-src.jar cp OpenJava/openjava.jar $LIB_DIR cp OpenJava/COPYRIGHT $LIB_DIR/openjava.license.txt cp RmiJdbc/dist/lib/*.jar $LIB_DIR cp ant/LICENSE $LIB_DIR/commons.license.txt cp csvjdbc/csvjdbc.jar $LIB_DIR cp csvjdbc/license.txt $LIB_DIR/csvjdbc.license.txt cp sqlline.jar $LIB_DIR cp sqlline/LICENSE $LIB_DIR/sqlline.license cp jline.jar $LIB_DIR cp jgrapht/jgrapht-jdk1.5.jar $LIB_DIR cp jgrapht/license-LGPL.txt $LIB_DIR/jgrapht.license.txt cp jgrapht/license-LGPL.txt $LIB_DIR/vjdbc.license.txt cp jgrapht/license-LGPL.txt $LIB_DIR/RmiJdbc.license.txt cp hsqldb/doc/hypersonic_lic.txt $LIB_DIR/hsqldb.license.txt cp hsqldb/lib/hsqldb.jar $LIB_DIR if [ -e postgresql-8.1-406.jdbc2.jar ]; then cp postgresql-8.1-406.jdbc2.jar $LIB_DIR fi cp commons-transaction-1.1.jar $LIB_DIR cp vjdbc/lib/vjdbc.jar $LIB_DIR cp vjdbc/lib/vjdbc_server.jar $LIB_DIR cp vjdbc/lib/commons-logging-1.1.jar $LIB_DIR cp vjdbc/lib/commons-pool-1.3.jar $LIB_DIR cp vjdbc/lib/commons-dbcp-1.2.1.jar $LIB_DIR cp vjdbc/lib/commons-digester-1.7.jar $LIB_DIR cp stlport/README $LIB_DIR/fennel/stlport.README.txt # get rid of this dangling symlink; it causes trouble for cp rm -f stlport/lib/libstlport_gcc_debug.so if $dist_fennel; then cp -d stlport/lib/$SO_3P_PATTERN $LIB_DIR/fennel cp -d boost/lib/$SO_3P_PATTERN $LIB_DIR/fennel fi if $remove_debug; then rm -f $LIB_DIR/fennel/*debug* rm -f $LIB_DIR/fennel/*gdp* fi cp boost/LICENSE_1_0.txt $LIB_DIR/fennel/boost.license.txt # TODO jvs 12-Mar-2005 # if dist_fennel; then # cp -d icu/lib/$SO_3P_PATTERN $LIB_DIR/fennel # fi # cp icu/license.html $LIB_DIR/fennel/icu.license.html # copy fennel libs if $dist_fennel; then cd $FENNEL_DIR cp -d libfennel/$SO_PATTERN $LIB_DIR/fennel cp -d farrago/$SO_PATTERN $LIB_DIR/fennel cp -d lucidera/libfennel_lu/$SO_PATTERN $LIB_DIR/fennel cp -d lucidera/farrago/$SO_PATTERN $LIB_DIR/fennel # if possible, strip rpath info if [ $cygwin = "false" ]; then if [ -e /usr/bin/chrpath ]; then /usr/bin/chrpath -d $LIB_DIR/fennel/*.so* fi fi # copy fennel resources cp common/*.properties $CATALOG_DIR/fennel fi # create farrago libs cd $DIST_DIR ant jar # copy farrago libs cd $FARRAGO_DIR cp COPYING $RELEASE_DIR if [ -e dist/VERSION ]; then cp dist/VERSION $RELEASE_DIR fi if [ -e dist/README ]; then cp dist/README $RELEASE_DIR fi cp dist/farrago.jar $LIB_DIR cp dist/vjdbc_servlet.war $LIB_DIR cp dist/plugin/*.jar $PLUGIN_DIR # copy other farrago artifacts if [ $cygwin = "true" ]; then cp dist/install/install.bat $INSTALL_DIR else cp dist/install/install.sh $INSTALL_DIR fi # Make a backup to get a mysql dump in the event that HSQLDB isn't being used ant backupCatalog cp catalog/backup/FarragoCatalog.* $CATALOG_DIR cp catalog/ReposStorage.properties $CATALOG_DIR if $dist_fennel; then cp catalog/backup/*.dat $CATALOG_DIR fi if [ $cygwin = "true" ]; then cp dist/bin/*.bat $BIN_DIR else cp dist/bin/* $BIN_DIR rm -f $BIN_DIR/*.bat fi # archive the whole thing up cd $TMP_DIR if [ $cygwin = "true" ]; then zip -r -y ../farrago.zip . else tar cv * | bzip2 -c >../farrago.tar.bz2 fi cd $FARRAGO_DIR rm -rf $TMP_DIR