예제 #1
0
        public void Test019()
        {
            string nativeSql = @"SELECT 
                                  c.CustomerId,
                                  c.CompanyName,
                                  c.LastName
                           FROM
                                customer c
                           WHERE c.CustomerId IN (SELECT r.CustomerId FROM invoice r WHERE r.DesignatedEmployeeId = 8)
                           GROUP BY c.CustomerID,
                                    c.CompanyName,
                                    c.LastName";

            SqlTableRef customer = SqlDml.TableRef(schema.Tables["customer"], "c");
            SqlTableRef invoice  = SqlDml.TableRef(schema.Tables["invoice"], "r");

            SqlSelect innerSelect = SqlDml.Select(invoice);

            innerSelect.Columns.Add(invoice["CustomerId"]);
            innerSelect.Where = invoice["DesignatedEmployeeId"] == 8;

            SqlSelect select = SqlDml.Select(customer);

            select.Columns.Add(customer["CustomerId"]);
            select.Columns.Add(customer["CompanyName"]);
            select.Columns.Add(customer["LastName"]);

            select.Where = SqlDml.In(customer["CustomerId"], innerSelect);

            select.GroupBy.Add(customer["CustomerID"]);
            select.GroupBy.Add(customer["CompanyName"]);
            select.GroupBy.Add(customer["LastName"]);

            Assert.IsTrue(CompareExecuteDataReader(nativeSql, select));
        }
예제 #2
0
        public void UnionTest()
        {
            SqlSelect s1 = SqlDml.Select(SqlDml.TableRef(Catalog.Schemas["main"].Tables["track"]));

            s1.Columns.Add(s1.From["TrackId"]);
            SqlSelect s2 = SqlDml.Select(SqlDml.TableRef(Catalog.Schemas["main"].Tables["track"]));

            s2.Columns.Add(s2.From["TrackId"]);
            SqlSelect s3 = SqlDml.Select(SqlDml.TableRef(Catalog.Schemas["main"].Tables["track"]));

            s3.Columns.Add(s3.From["TrackId"]);

            Console.WriteLine(sqlDriver.Compile(s1.Union(s2)).GetCommandText());
            Console.WriteLine(sqlDriver.Compile(s1.Union(s2).Union(s3)).GetCommandText());
            Console.WriteLine(sqlDriver.Compile(s1.Union(s2.Union(s3))).GetCommandText());
            Console.WriteLine(sqlDriver.Compile(SqlDml.Union(s1, s2)).GetCommandText());
            Console.WriteLine(sqlDriver.Compile(SqlDml.Union(s1, s1.Union(s2))).GetCommandText());
            Console.WriteLine(sqlDriver.Compile(SqlDml.Union(s1.Union(s2), s1)).GetCommandText());
            Console.WriteLine(sqlDriver.Compile(SqlDml.Union(s1.Union(s2), s1.Union(s2))).GetCommandText());
            s3.Where = SqlDml.In(1, s1.Union(s2));
            Console.WriteLine(sqlDriver.Compile(s3).GetCommandText());
            SqlQueryRef qr = SqlDml.QueryRef(s1.Union(s2), "qr");

            Assert.Greater(qr.Columns.Count, 0);
        }
예제 #3
0
        private void JoinViaIn(SqlStatement statement, SqlSelect @select)
        {
            SqlTableRef table = GetStatementTable(statement);

            SqlExpression where = GetStatementWhere(statement);
            JoinedTableRef      = table;
            PrimaryIndexMapping indexMapping = PrimaryIndexes[0];
            var columns = new List <ColumnInfo>();

            foreach (ColumnInfo columnInfo in indexMapping.PrimaryIndex.KeyColumns.Keys)
            {
                SqlSelect s = select.ShallowClone();
                foreach (ColumnInfo column in columns)
                {
                    SqlBinary ex = SqlDml.Equals(SqlDml.TableColumn(s.From, column.Name), SqlDml.TableColumn(table, column.Name));
                    s.Where = s.Where.IsNullReference() ? ex : SqlDml.And(s.Where, ex);
                }
                s.Columns.Clear();
                s.Columns.Add(SqlDml.TableColumn(s.From, columnInfo.Name));
                SqlBinary @in = SqlDml.In(SqlDml.TableColumn(table, columnInfo.Name), s);
                @where = @where.IsNullReference() ? @in : SqlDml.And(@where, @in);
                columns.Add(columnInfo);
            }
            SetStatementWhere(statement, where);
        }
        public void Test019()
        {
            string nativeSql = @"SELECT 
                                    c.customer_id,
                                    c.first_name,
                                    c.last_name
                                FROM
                                    customer c
                                WHERE c.customer_id IN (SELECT r.customer_id FROM rental r WHERE r.inventory_id = 239)
                                GROUP BY c.customer_id,
                                    c.first_name,
                                    c.last_name";

            SqlTableRef customer = SqlDml.TableRef(schema.Tables["customer"], "c");
            SqlTableRef rental   = SqlDml.TableRef(schema.Tables["rental"], "r");

            SqlSelect innerSelect = SqlDml.Select(rental);

            innerSelect.Columns.Add(rental["customer_id"]);
            innerSelect.Where = rental["inventory_id"] == 239;

            SqlSelect select = SqlDml.Select(customer);

            select.Columns.Add(customer["customer_id"]);
            select.Columns.Add(customer["first_name"]);
            select.Columns.Add(customer["last_name"]);

            select.Where = SqlDml.In(customer["customer_id"], innerSelect);

            select.GroupBy.Add(customer["customer_id"]);
            select.GroupBy.Add(customer["first_name"]);
            select.GroupBy.Add(customer["last_name"]);

            Assert.IsTrue(CompareExecuteDataReader(nativeSql, select));
        }
예제 #5
0
        public override void Visit(SqlBinary node)
        {
            var right = node.Right as SqlArray;

            if (!right.IsNullReference() && (node.NodeType == SqlNodeType.In || node.NodeType == SqlNodeType.NotIn))
            {
                var row = SqlDml.Row(right.GetValues().Select(value => SqlDml.Literal(value)).ToArray());
                base.Visit(node.NodeType == SqlNodeType.In ? SqlDml.In(node.Left, row) : SqlDml.NotIn(node.Left, row));
            }
            else
            {
                switch (node.NodeType)
                {
                case SqlNodeType.DateTimeOffsetMinusDateTimeOffset:
                    (node.Left - node.Right).AcceptVisitor(this);
                    return;

                case SqlNodeType.DateTimeOffsetMinusInterval:
                    (node.Left - node.Right).AcceptVisitor(this);
                    return;

                case SqlNodeType.DateTimeOffsetPlusInterval:
                    (node.Left + node.Right).AcceptVisitor(this);
                    return;
                }
                base.Visit(node);
            }
        }
예제 #6
0
        /// <inheritdoc/>
        protected override ISqlCompileUnit BuildExtractTableAndDomainConstraintsQuery(ExtractionContext context)
        {
            var tableMap        = context.TableMap;
            var domainMap       = context.DomainMap;
            var constraintTable = PgConstraint;
            var select          = SqlDml.Select(constraintTable);

            select.Where = SqlDml.In(constraintTable["conrelid"], CreateOidRow(tableMap.Keys)) ||
                           SqlDml.In(constraintTable["contypid"], CreateOidRow(domainMap.Keys));

            select.Columns.AddRange(constraintTable["conname"],
                                    constraintTable["contype"],
                                    constraintTable["condeferrable"],
                                    constraintTable["condeferred"],
                                    constraintTable["conrelid"],
                                    constraintTable["contypid"],
                                    constraintTable["conkey"],
                                    SqlDml.ColumnRef(
                                        SqlDml.Column(SqlDml.FunctionCall("pg_get_constraintdef", constraintTable["oid"])), "consrc"),
                                    constraintTable["confrelid"],
                                    constraintTable["confkey"],
                                    constraintTable["confupdtype"],
                                    constraintTable["confdeltype"],
                                    constraintTable["confmatchtype"]);
            return(select);
        }
예제 #7
0
        /// <inheritdoc/>
        protected override ISqlCompileUnit BuildExtractTableAndViewColumnsQuery(ExtractionContext context)
        {
            var tableMap           = context.TableMap;
            var viewMap            = context.ViewMap;
            var columnsTable       = PgAttribute;
            var defaultValuesTable = PgAttrDef;
            var typesTable         = PgType;

            var select = SqlDml.Select(columnsTable
                                       .LeftOuterJoin(defaultValuesTable,
                                                      columnsTable["attrelid"] == defaultValuesTable["adrelid"] &&
                                                      columnsTable["attnum"] == defaultValuesTable["adnum"])
                                       .InnerJoin(typesTable, typesTable["oid"] == columnsTable["atttypid"]));

            select.Where = columnsTable["attisdropped"] == false &&
                           columnsTable["attnum"] > 0 &&
                           (SqlDml.In(columnsTable["attrelid"], CreateOidRow(tableMap.Keys)) ||
                            SqlDml.In(columnsTable["attrelid"], CreateOidRow(viewMap.Keys)));

            select.Columns.Add(columnsTable["attrelid"]);
            select.Columns.Add(columnsTable["attnum"]);
            select.Columns.Add(columnsTable["attname"]);
            select.Columns.Add(typesTable["typname"]);
            select.Columns.Add(columnsTable["atttypmod"]);
            select.Columns.Add(columnsTable["attnotnull"]);
            select.Columns.Add(columnsTable["atthasdef"]);
            select.Columns.Add(SqlDml.ColumnRef(SqlDml.Column(
                                                    SqlDml.FunctionCall("pg_get_expr", defaultValuesTable["adbin"], defaultValuesTable["adrelid"])), "adsrc"));
            select.OrderBy.Add(columnsTable["attrelid"]);
            select.OrderBy.Add(columnsTable["attnum"]);
            return(select);
        }
        private void JoinViaIn(SqlStatement statement, SqlSelect select)
        {
            var table = GetStatementTable(statement);

            var where      = GetStatementWhere(statement);
            JoinedTableRef = table;
            var indexMapping = PrimaryIndexes[0];
            var columns      = new List <ColumnInfo>();

            foreach (var columnInfo in indexMapping.PrimaryIndex.KeyColumns.Keys)
            {
                var s = (SqlSelect)select.Clone();
                foreach (var column in columns)
                {
                    var ex = SqlDml.Equals(s.From.Columns[column.Name], table.Columns[column.Name]);
                    s.Where = s.Where.IsNullReference() ? ex : SqlDml.And(s.Where, ex);
                }
                var existingColumns = s.Columns.ToChainedBuffer();
                s.Columns.Clear();
                var columnToAdd = existingColumns.First(c => c.Name.Equals(columnInfo.Name, StringComparison.Ordinal));
                s.Columns.Add(columnToAdd);
                var @in = SqlDml.In(SqlDml.TableColumn(table, columnInfo.Name), s);
                where = where.IsNullReference() ? @in : SqlDml.And(where, @in);
                columns.Add(columnInfo);
            }

            SetStatementWhere(statement, where);
        }
예제 #9
0
        /// <inheritdoc/>
        protected override ISqlCompileUnit BuildExtractSequencesQuery(ExtractionContext context)
        {
            var sequenceMap = context.SequenceMap;
            // select all the sequences registered in map
            var tableRef = PgSequence;
            var select   = SqlDml.Select(tableRef);

            select.Where = SqlDml.In(tableRef["seqrelid"], SqlDml.Array(sequenceMap.Keys.ToArray()));
            return(select);
        }
예제 #10
0
        private SqlSelect BuildFilteredQuery(IndexInfo index)
        {
            var underlyingIndex = index.UnderlyingIndexes[0];
            var baseQuery       = BuildProviderQuery(underlyingIndex);

            SqlExpression filter           = null;
            var           type             = index.ReflectedType;
            var           discriminatorMap = type.Hierarchy.TypeDiscriminatorMap;
            var           filterByTypes    = index.FilterByTypes.ToList();

            if (underlyingIndex.IsTyped && discriminatorMap != null)
            {
                var columnType = discriminatorMap.Column.ValueType;
                var discriminatorColumnIndex = underlyingIndex.Columns
                                               .Where(c => !c.Field.IsTypeId)
                                               .Select((c, i) => new { c, i })
                                               .Where(p => p.c == discriminatorMap.Column)
                                               .Single().i;
                var discriminatorColumn = baseQuery.From.Columns[discriminatorColumnIndex];
                var containsDefault     = filterByTypes.Contains(discriminatorMap.Default);
                var values = filterByTypes
                             .Select(t => GetDiscriminatorValue(discriminatorMap, t.TypeDiscriminatorValue));
                if (filterByTypes.Count == 1)
                {
                    var discriminatorValue = GetDiscriminatorValue(discriminatorMap, filterByTypes.First().TypeDiscriminatorValue);
                    filter = discriminatorColumn == SqlDml.Literal(discriminatorValue);
                }
                else
                {
                    filter = SqlDml.In(discriminatorColumn, SqlDml.Array(values));
                    if (containsDefault)
                    {
                        var allValues = discriminatorMap
                                        .Select(p => GetDiscriminatorValue(discriminatorMap, p.First));
                        filter |= SqlDml.NotIn(discriminatorColumn, SqlDml.Array(allValues));
                    }
                }
            }
            else
            {
                var typeIdColumn = baseQuery.Columns[Handlers.Domain.Handlers.NameBuilder.TypeIdColumnName];
                var typeIds      = filterByTypes.Select(t => TypeIdRegistry[t]).ToArray();
                filter = filterByTypes.Count == 1
          ? typeIdColumn == TypeIdRegistry[filterByTypes.First()]
          : SqlDml.In(typeIdColumn, SqlDml.Array(typeIds));
            }
            var query = SqlDml.Select(baseQuery.From);

            query.Columns.AddRange(baseQuery.Columns);
            query.Where = filter;
            return(query);
        }
예제 #11
0
        public static SqlExpression DateTimeDaysInMonth(
            [Type(typeof(int))] SqlExpression year,
            [Type(typeof(int))] SqlExpression month)
        {
            var februaryCase = SqlDml.Case();

            februaryCase.Add(DateTimeIsLeapYear(year), 29);
            februaryCase.Else = 28;

            var result = SqlDml.Case();

            result.Add(SqlDml.In(month, SqlDml.Array(1, 3, 5, 7, 8, 10, 12)), 31);
            result.Add(month == 2, februaryCase);
            result.Else = 30;

            return(result);
        }
예제 #12
0
        public void ArrayTest()//TODO: Find reason why this pattern is structured like this.(Malisa)
        {
            SqlArray <int> i = SqlDml.Array(new int[] { 1, 2 });

            i.Values[0] = 10;
            SqlSelect select = SqlDml.Select();

            select.Where = SqlDml.In(1, i);

            MemoryStream    ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();

            bf.Serialize(ms, select);

            ms.Seek(0, SeekOrigin.Begin);
            select = (SqlSelect)bf.Deserialize(ms);

            Console.WriteLine(SqlDriver.Compile(select).GetCommandText());
        }
예제 #13
0
        public void Test021()
        {
            string nativeSql = @"SELECT 
                                  f.TrackId,
                                  f.Name,
                                  f.UnitPrice,
                                  f.AlbumId
                           FROM track f
                           WHERE f.AlbumId in (2, 8)
                           ORDER BY f.TrackId";

            SqlTableRef track  = SqlDml.TableRef(schema.Tables["track"], "f");
            SqlSelect   select = SqlDml.Select(track);

            select.Columns.AddRange(track["TrackId"], track["Name"], track["UnitPrice"], track["AlbumId"]);
            select.Where = SqlDml.In(track["AlbumId"], SqlDml.Row(2, 8));
            select.OrderBy.Add(track["TrackId"]);

            Assert.IsTrue(CompareExecuteDataReader(nativeSql, select));
        }
예제 #14
0
        public static SqlExpression EnumerableContains(
            MemberInfo member, SqlExpression sequence, SqlExpression value)
        {
            var method = (MethodInfo)member;

            // Try string.Contains first
            if (method.GetGenericArguments()[0] == typeof(char))
            {
                return(StringContains(sequence, value));
            }
            // Otherwise translate into general IN clause
            var container = sequence as SqlContainer;

            if (container.IsNullReference())
            {
                throw new NotSupportedException(Strings.ExTranslationOfInContainsIsNotSupportedInThisCase);
            }
            var items = container.Value as IEnumerable;

            if (items == null)
            {
                throw new NotSupportedException(Strings.ExTranslationOfInContainsIsNotSupportedInThisCase);
            }
            var expressions = new List <SqlExpression>();

            foreach (var item in items)
            {
                object literal = null;
                if (item.GetType().StripNullable().IsEnum)
                {
                    literal = Convert.ChangeType(item, Enum.GetUnderlyingType(item.GetType()));
                }
                else
                {
                    literal = item;
                }
                expressions.Add(SqlDml.Literal(literal));
            }
            return(SqlDml.In(value, SqlDml.Row(expressions)));
        }
예제 #15
0
        protected override void ExtractSequenses(ExtractionContext context)
        {
            var sequenceMap = context.SequenceMap;

            if (sequenceMap.Count > 0)
            {
                // select all the sequences registered in map
                var tableRef = PgSequence;
                var select   = SqlDml.Select(tableRef);
                select.Where = SqlDml.In(tableRef["seqrelid"], SqlDml.Array(sequenceMap.Keys.ToArray()));

                using (DbCommand cmd = Connection.CreateCommand(select))
                    using (DbDataReader dr = cmd.ExecuteReader()) {
                        while (dr.Read())
                        {
                            var seqId    = Convert.ToInt64(dr["seqrelid"]);
                            var sequence = context.SequenceMap[seqId];
                            ReadSequenceDescriptor(dr, sequence.SequenceDescriptor);
                        }
                    }
            }
        }
예제 #16
0
        /// <inheritdoc/>
        protected override ISqlCompileUnit BuildExtractTableIndexesQuery(ExtractionContext context)
        {
            var tableMap         = context.TableMap;
            var tableSpacesTable = PgTablespace;
            var relationsTable   = PgClass;
            var indexTable       = PgIndex;
            var dependencyTable  = PgDepend;

            //subselect that index was not created automatically
            var subSelect = SqlDml.Select(dependencyTable);

            subSelect.Where = dependencyTable["classid"] == PgClassOid &&
                              dependencyTable["objid"] == indexTable["indexrelid"] &&
                              dependencyTable["deptype"] == 'i';
            subSelect.Columns.Add(dependencyTable[0]);

            //not automatically created indexes of our tables
            var select = SqlDml.Select(indexTable
                                       .InnerJoin(relationsTable, relationsTable["oid"] == indexTable["indexrelid"])
                                       .LeftOuterJoin(tableSpacesTable, tableSpacesTable["oid"] == relationsTable["reltablespace"]));

            select.Where = SqlDml.In(indexTable["indrelid"], CreateOidRow(tableMap.Keys)) && !SqlDml.Exists(subSelect);
            select.Columns.Add(indexTable["indrelid"]);
            select.Columns.Add(indexTable["indexrelid"]);
            select.Columns.Add(relationsTable["relname"]);
            select.Columns.Add(indexTable["indisunique"]);
            select.Columns.Add(indexTable["indisclustered"]);
            select.Columns.Add(indexTable["indkey"]);
            select.Columns.Add(tableSpacesTable["spcname"]);
            select.Columns.Add(indexTable["indnatts"]);
            select.Columns.Add(SqlDml.FunctionCall("pg_get_expr", indexTable["indexprs"], indexTable["indrelid"], true),
                               "indexprstext");
            select.Columns.Add(SqlDml.FunctionCall("pg_get_expr", indexTable["indpred"], indexTable["indrelid"], true),
                               "indpredtext");
            select.Columns.Add(SqlDml.FunctionCall("pg_get_indexdef", indexTable["indexrelid"]), "inddef");
            AddSpecialIndexQueryColumns(select, tableSpacesTable, relationsTable, indexTable, dependencyTable);
            return(select);
        }
        public void Test021()
        {
            string nativeSql = @"SELECT 
                                  f.film_id,
                                  f.title,
                                  f.description,
                                  f.release_year,
                                  f.rating
                                FROM
                                  film f
                                WHERE
                                  f.rating in ('PG', 'PG-13', 'R')
                                ORDER BY f.film_id";

            SqlTableRef film   = SqlDml.TableRef(schema.Tables["film"], "f");
            SqlSelect   select = SqlDml.Select(film);

            select.Columns.AddRange(film["film_id"], film["title"], film["description"], film["release_year"], film["rating"]);
            select.Where = SqlDml.In(film["rating"], SqlDml.Row("PG", "PG-13", "R"));
            select.OrderBy.Add(film["film_id"]);

            Assert.IsTrue(CompareExecuteDataReader(nativeSql, select));
        }
예제 #18
0
        private void ProvideExtensionMetadataFilter(SqlDelete delete)
        {
            var knownExtensions = SqlDml.Array(WellKnown.DomainModelExtensionName, WellKnown.PartialIndexDefinitionsExtensionName);

            delete.Where = SqlDml.In(delete.Delete[mapping.ExtensionName], knownExtensions);
        }
예제 #19
0
        // Consructors

        protected override void ExtractTableIndexes(ExtractionContext context)
        {
            var tableMap     = context.TableMap;
            var tableColumns = context.TableColumnMap;

            if (tableMap.Count > 0)
            {
                var tableSpacesTable = PgTablespace;
                var relationsTable   = PgClass;
                var indexTable       = PgIndex;
                var dependencyTable  = PgDepend;

                //subselect that index was not created automatically
                var subSelect = SqlDml.Select(dependencyTable);
                subSelect.Where = dependencyTable["classid"] == PgClassOid &&
                                  dependencyTable["objid"] == indexTable["indexrelid"] &&
                                  dependencyTable["deptype"] == 'i';
                subSelect.Columns.Add(dependencyTable[0]);

                //not automatically created indexes of our tables
                var select = SqlDml.Select(indexTable
                                           .InnerJoin(relationsTable, relationsTable["oid"] == indexTable["indexrelid"])
                                           .LeftOuterJoin(tableSpacesTable, tableSpacesTable["oid"] == relationsTable["reltablespace"]));
                select.Where = SqlDml.In(indexTable["indrelid"], CreateOidRow(tableMap.Keys)) && !SqlDml.Exists(subSelect);
                select.Columns.Add(indexTable["indrelid"]);
                select.Columns.Add(indexTable["indexrelid"]);
                select.Columns.Add(relationsTable["relname"]);
                select.Columns.Add(indexTable["indisunique"]);
                select.Columns.Add(indexTable["indisclustered"]);
                select.Columns.Add(indexTable["indkey"]);
                select.Columns.Add(tableSpacesTable["spcname"]);
                select.Columns.Add(indexTable["indnatts"]);
                select.Columns.Add(SqlDml.FunctionCall("pg_get_expr", indexTable["indexprs"], indexTable["indrelid"], true), "indexprstext");
                select.Columns.Add(SqlDml.FunctionCall("pg_get_expr", indexTable["indpred"], indexTable["indrelid"], true), "indpredtext");
                select.Columns.Add(SqlDml.FunctionCall("pg_get_indexdef", indexTable["indexrelid"]), "inddef");
                AddSpecialIndexQueryColumns(select, tableSpacesTable, relationsTable, indexTable, dependencyTable);

                int maxColumnNumber = 0;
                using (var command = Connection.CreateCommand(select))
                    using (var dataReader = command.ExecuteReader()) {
                        while (dataReader.Read())
                        {
                            var tableIdentifier = Convert.ToInt64(dataReader["indrelid"]);
                            var indexIdentifier = Convert.ToInt64(dataReader["indexrelid"]);
                            var indexName       = dataReader["relname"].ToString();
                            var isUnique        = dataReader.GetBoolean(dataReader.GetOrdinal("indisunique"));
                            var isClustered     = dataReader.GetBoolean(dataReader.GetOrdinal("indisclustered"));
                            var indexKey        = (short[])dataReader["indkey"];

                            var tablespaceName   = (dataReader["spcname"] != DBNull.Value) ? dataReader["spcname"].ToString() : (string)null;
                            var filterExpression = (dataReader["indpredtext"] != DBNull.Value) ? dataReader["indpredtext"].ToString() : string.Empty;

                            var table = tableMap[tableIdentifier];

                            var fullTextRegex = @"(?<=CREATE INDEX \S+ ON \S+ USING (?:gist|gin)(?:\s|\S)*)to_tsvector\('(\w+)'::regconfig, \(*(?:(?:\s|\)|\(|\|)*(?:\(""(\S+)""\)|'\s')::text)+\)";
                            var indexScript   = dataReader["inddef"].ToString();
                            var matches       = Regex.Matches(indexScript, fullTextRegex, RegexOptions.Compiled);
                            if (matches.Count > 0)
                            {
                                // Fulltext index
                                var fullTextIndex = table.CreateFullTextIndex(indexName);
                                foreach (Match match in matches)
                                {
                                    var columnConfigurationName = match.Groups[1].Value;
                                    foreach (Capture capture in match.Groups[2].Captures)
                                    {
                                        var columnName     = capture.Value;
                                        var fullTextColumn = fullTextIndex.Columns[columnName] ?? fullTextIndex.CreateIndexColumn(table.Columns.Single(column => column.Name == columnName));
                                        if (fullTextColumn.Languages[columnConfigurationName] == null)
                                        {
                                            fullTextColumn.Languages.Add(new Language(columnConfigurationName));
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //Regular index
                                var index = table.CreateIndex(indexName);
                                index.IsBitmap  = false;
                                index.IsUnique  = isUnique;
                                index.Filegroup = tablespaceName;
                                if (!string.IsNullOrEmpty(filterExpression))
                                {
                                    index.Where = SqlDml.Native(filterExpression);
                                }

                                // Expression-based index
                                var some = dataReader["indexprstext"];
                                if (some != DBNull.Value)
                                {
                                    context.ExpressionIndexMap[indexIdentifier] = new ExpressionIndexInfo(index, indexKey);
                                    int columnNumber = dataReader.GetInt16(dataReader.GetOrdinal("indnatts"));
                                    if (columnNumber > maxColumnNumber)
                                    {
                                        maxColumnNumber = columnNumber;
                                    }
                                }
                                else
                                {
                                    for (int j = 0; j < indexKey.Length; j++)
                                    {
                                        int colIndex = indexKey[j];
                                        if (colIndex > 0)
                                        {
                                            index.CreateIndexColumn(tableColumns[tableIdentifier][colIndex], true);
                                        }
                                        else
                                        {
                                            int z = 7;
                                            //column index is 0
                                            //this means that this index column is an expression
                                            //which is not possible with SqlDom tables
                                        }
                                    }
                                }
                                ReadSpecialIndexProperties(dataReader, index);
                            }
                        }
                    }

                var expressionIndexMap = context.ExpressionIndexMap;

                if (expressionIndexMap.Count > 0)
                {
                    select = SqlDml.Select(indexTable);
                    select.Columns.Add(indexTable["indrelid"]);
                    select.Columns.Add(indexTable["indexrelid"]);

                    for (int i = 1; i <= maxColumnNumber; i++)
                    {
                        select.Columns.Add(SqlDml.FunctionCall("pg_get_indexdef", indexTable["indexrelid"], i, true), i.ToString());
                    }
                    select.Where = SqlDml.In(indexTable["indexrelid"], SqlDml.Array(expressionIndexMap.Keys.ToArray()));

                    using (var command = Connection.CreateCommand(select))
                        using (var dataReader = command.ExecuteReader()) {
                            while (dataReader.Read())
                            {
                                var exprIndexInfo = expressionIndexMap[Convert.ToInt64(dataReader[1])];
                                for (int j = 0; j < exprIndexInfo.Columns.Length; j++)
                                {
                                    int colIndex = exprIndexInfo.Columns[j];
                                    if (colIndex > 0)
                                    {
                                        exprIndexInfo.Index.CreateIndexColumn(tableColumns[Convert.ToInt64(dataReader[0])][colIndex], true);
                                    }
                                    else
                                    {
                                        exprIndexInfo.Index.CreateIndexColumn(SqlDml.Native(dataReader[(j + 1).ToString()].ToString()));
                                    }
                                }
                            }
                        }
                }
            }
        }