<|start_filename|>core/src/main/java/io/questdb/cutlass/pgwire/PGBasicAuthenticator.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.cutlass.pgwire;

import io.questdb.cairo.CairoSecurityContext;
import io.questdb.cairo.security.AllowAllCairoSecurityContext;
import io.questdb.griffin.SqlException;
import io.questdb.log.Log;
import io.questdb.log.LogFactory;
import io.questdb.std.Chars;
import io.questdb.std.str.DirectByteCharSequence;

public class PGBasicAuthenticator implements PGAuthenticator {
    private static final Log LOG = LogFactory.getLog(PGBasicAuthenticator.class);

    private final String username;
    private final String password;
    private final DirectByteCharSequence dbcs = new DirectByteCharSequence();

    public PGBasicAuthenticator(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public CairoSecurityContext authenticate(
            CharSequence username,
            long msg,
            long msgLimit
    ) throws BadProtocolException, SqlException {
        if (Chars.equals(this.username, username)) {
            // check 'p' message
            // +1 is 'type' byte that message length does not account for
            long hi = PGConnectionContext.getStringLength(msg, msgLimit, "bad password length");
            dbcs.of(msg, hi);

            // check password
            if (Chars.equals(this.password, dbcs)) {
                return AllowAllCairoSecurityContext.INSTANCE;
            }
            LOG.error().$("invalid password [user=").$(username).$(']').$();
        } else {
            LOG.error().$("invalid user [").$(username).$(']').$();
        }
        // -1 position here means we will not send it to postgresql
        throw SqlException.$(-1, "invalid username/password");
    }
}


<|start_filename|>core/src/main/java/io/questdb/cutlass/pgwire/PGJobContext.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.cutlass.pgwire;

import io.questdb.MessageBus;
import io.questdb.cairo.CairoEngine;
import io.questdb.griffin.FunctionFactoryCache;
import io.questdb.griffin.SqlCompiler;
import io.questdb.network.PeerDisconnectedException;
import io.questdb.network.PeerIsSlowToReadException;
import io.questdb.network.PeerIsSlowToWriteException;
import io.questdb.std.AssociativeCache;
import io.questdb.std.Misc;
import io.questdb.std.WeakAutoClosableObjectPool;

import java.io.Closeable;

public class PGJobContext implements Closeable {

    private final SqlCompiler compiler;
    private final AssociativeCache<TypesAndSelect> selectAndTypesCache;
    private final WeakAutoClosableObjectPool<TypesAndSelect> selectAndTypesPool;

    public PGJobContext(PGWireConfiguration configuration, CairoEngine engine, MessageBus messageBus, FunctionFactoryCache functionFactoryCache) {
        this.compiler = new SqlCompiler(engine, messageBus, functionFactoryCache);
        this.selectAndTypesCache = new AssociativeCache<>(
                configuration.getFactoryCacheColumnCount(),
                configuration.getFactoryCacheRowCount()
        );
        this.selectAndTypesPool = new WeakAutoClosableObjectPool<>(
                TypesAndSelect::new,
                configuration.getFactoryCacheColumnCount() * configuration.getFactoryCacheRowCount()
        );
    }

    @Override
    public void close() {
        Misc.free(compiler);
        Misc.free(selectAndTypesCache);
    }

    public void handleClientOperation(PGConnectionContext context, int operation)
            throws PeerIsSlowToWriteException,
            PeerIsSlowToReadException,
            PeerDisconnectedException,
            BadProtocolException {
        context.handleClientOperation(compiler, selectAndTypesCache, selectAndTypesPool, operation);
    }
}


<|start_filename|>core/src/main/java/io/questdb/griffin/engine/AbstractVirtualFunctionRecordCursor.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.griffin.engine;

import io.questdb.cairo.sql.*;
import io.questdb.griffin.engine.groupby.GroupByUtils;
import io.questdb.std.Misc;
import io.questdb.std.ObjList;

public abstract class AbstractVirtualFunctionRecordCursor implements RecordCursor {
    protected final VirtualRecord recordA;
    private final VirtualRecord recordB;
    protected RecordCursor baseCursor;
    private final ObjList<Function> functions;
    private final boolean supportsRandomAccess;

    public AbstractVirtualFunctionRecordCursor(ObjList<Function> functions, boolean supportsRandomAccess) {
        this.functions = functions;
        if (supportsRandomAccess) {
            this.recordA = new VirtualRecord(functions);
            this.recordB = new VirtualRecord(functions);
        } else {
            this.recordA = new VirtualRecordNoRowid(functions);
            this.recordB = null;
        }
        this.supportsRandomAccess = supportsRandomAccess;
    }

    @Override
    public void close() {
        baseCursor = Misc.free(baseCursor);
    }

    @Override
    public Record getRecord() {
        return recordA;
    }

    @Override
    public boolean hasNext() {
        return baseCursor.hasNext();
    }

    @Override
    public long size() {
        return baseCursor.size();
    }

    @Override
    public Record getRecordB() {
        if (recordB != null) {
            return recordB;
        }
        throw new UnsupportedOperationException();
    }

    @Override
    public void recordAt(Record record, long atRowId) {
        if (supportsRandomAccess) {
            baseCursor.recordAt(((VirtualRecord) record).getBaseRecord(), atRowId);
        } else {
            throw new UnsupportedOperationException();
        }
    }

    @Override
    public SymbolTable getSymbolTable(int columnIndex) {
        return (SymbolTable) functions.getQuick(columnIndex);
    }

    @Override
    public void toTop() {
        baseCursor.toTop();
        GroupByUtils.toTop(functions);
    }

    public void of(RecordCursor cursor) {
        this.baseCursor = cursor;
        recordA.of(baseCursor.getRecord());
        if (recordB != null) {
            recordB.of(baseCursor.getRecordB());
        }
    }
}


<|start_filename|>core/src/test/java/io/questdb/std/ObjStackTest.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.std;

import org.junit.Assert;
import org.junit.Test;

public class ObjStackTest {
    @Test
    public void testLifo1ElementInOut() {
         ObjStack<Integer> s = new ObjStack<>();
        s.push(1);
        int i = s.pop();

        Assert.assertEquals(1, i);
        Assert.assertNull(s.pop());
    }

    @Test
    public void testLifo10ElementsInOut() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 10; i++){
            s.push(i);
        }

        for(int i = 9; i >= 0; i--){
            Integer r = s.pop();
            Assert.assertEquals((Integer)i, r);
        }
        Assert.assertNull(s.pop());
    }

    @Test
    public void testLifo120ElementsInOut() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 20; i++){
            s.push(i);
        }

        for(int i = 19; i >= 0; i--){
            Integer r = s.pop();
            Assert.assertEquals((Integer)i, r);
        }
        Assert.assertNull(s.pop());
    }

    @Test
    public void testLifo2In1Out() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 1000; i++){
            s.push(2*i);
            s.push(2*i + 1);

            Integer r = s.pop();
            Assert.assertEquals((Integer)(2*i + 1), r);
            Assert.assertEquals(i + 1, s.size());
        }
    }

    @Test
    public void testLifo2In2Out() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 1000; i++){
            s.push(2*i);
            s.push(2*i + 1);

            Integer r = s.pop();
            Assert.assertEquals((Integer)(2*i + 1), r);

            Integer r2 = s.pop();
            Assert.assertEquals((Integer)(2*i), r2);

            Assert.assertEquals(0, s.size());
        }
    }

    @Test
    public void peekLifoTest() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 10; i++){
            s.push(i);
        }

        Assert.assertEquals(s.size() - 1, (int)s.peek());
        for(int i = 0; i < 10; i++){
            Assert.assertEquals(s.size() - i - 1, (int)s.peek(i));
        }
    }

    @Test
    public void clearTest() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 10; i++){
            s.push(i);
        }

        Assert.assertEquals(10, s.size());
        s.clear();
        Assert.assertEquals(0, s.size());

        for(int i = 0; i < 10; i++){
            Assert.assertNull(s.peek(i));
        }
    }

    @Test
    public void updateTest() {
         ObjStack<Integer> s = new ObjStack<>();
        for(int i = 0; i < 10; i++){
            s.push(i);
        }

        Assert.assertEquals(s.size() - 1, (int)s.peek());
        s.update(20);
        Assert.assertEquals(20, (int)s.peek());
        Assert.assertEquals(20, (int)s.pop());
    }

    @Test
    public void notEmptyTest() {
         ObjStack<Integer> s = new ObjStack<>();
        Assert.assertFalse(s.notEmpty());
        s.push(1);
        Assert.assertTrue(s.notEmpty());
        s.pop();
        Assert.assertFalse(s.notEmpty());
    }

    @Test
    public void fifoConstCapacityTest() {
         ObjStack<Integer> s = new ObjStack<>(3);
        for(int i = 0; i < 10; i++){
            s.push(2*i);
        }
        Assert.assertEquals(10, s.size());
    }

    @Test
    public void constCapacityTest() {
        ObjStack<Integer> q = new ObjStack<>(3);
        for(int i = 0; i < 10; i++){
            q.push(2*i);
        }
        Assert.assertEquals(10, q.size());
    }
}


<|start_filename|>ci/prettier.config.js<|end_filename|>
module.exports = {
  overrides: [
    {
      files: "*.yml",
      options: {
        parser: "yaml",
      },
    },
  ],
}


<|start_filename|>core/src/main/java/io/questdb/log/LogWriterConfig.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.log;

public class LogWriterConfig {
    private final String scope;
    private final int level;
    private final LogWriterFactory factory;

    public LogWriterConfig(int level, LogWriterFactory factory) {
        this("", level, factory);
    }

    public LogWriterConfig(String scope, int level, LogWriterFactory factory) {
        this.scope = scope == null ? "" : scope;
        this.level = level;
        this.factory = factory;
    }

    public LogWriterFactory getFactory() {
        return factory;
    }

    public int getLevel() {
        return level;
    }

    public String getScope() {
        return scope;
    }
}


<|start_filename|>core/src/main/java/io/questdb/griffin/engine/analytic/AnalyticFunction.java<|end_filename|>
/*******************************************************************************
 *    ___                  _   ____  ____
 *   / _ \ _   _  ___  ___| |_|  _ \| __ )
 *  | | | | | | |/ _ \/ __| __| | | |  _ \
 *  | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *   \__\_\\__,_|\___||___/\__|____/|____/
 *
 * Copyright (C) 2014-2016 Appsicle
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

package io.questdb.griffin.engine.analytic;

import io.questdb.cairo.sql.AnalyticSPI;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;

public interface AnalyticFunction extends Function {
    int STREAM = 1;
    int TWO_PASS = 2;
    int THREE_PASS = 3;

    void pass1(Record record, long recordOffset, AnalyticSPI spi);

    void preparePass2(RecordCursor cursor);

    void pass2(Record record);

    void reset();

    void setColumnIndex(int columnIndex);
}


<|start_filename|>core/src/test/java/io/questdb/cairo/map/RecordValueSinkFactoryTest.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.cairo.map;

import io.questdb.cairo.*;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.StaticSymbolTable;
import io.questdb.std.BytecodeAssembler;
import io.questdb.std.Numbers;
import io.questdb.std.Rnd;
import org.junit.Assert;
import org.junit.Test;

public class RecordValueSinkFactoryTest extends AbstractCairoTest {
    @Test
    public void testAllSupportedTypes() {
        SingleColumnType keyTypes = new SingleColumnType(ColumnType.INT);
        try (TableModel model = new TableModel(configuration, "all", PartitionBy.NONE)
                .col("int", ColumnType.INT)
                .col("short", ColumnType.SHORT)
                .col("byte", ColumnType.BYTE)
                .col("double", ColumnType.DOUBLE)
                .col("float", ColumnType.FLOAT)
                .col("long", ColumnType.LONG)
                .col("sym", ColumnType.SYMBOL).symbolCapacity(64)
                .col("bool", ColumnType.BOOLEAN)
                .col("date", ColumnType.DATE)
                .col("ts", ColumnType.TIMESTAMP)
        ) {
            CairoTestUtils.create(model);
        }

        final int N = 1024;
        final Rnd rnd = new Rnd();
        try (TableWriter writer = new TableWriter(configuration, "all")) {

            for (int i = 0; i < N; i++) {
                TableWriter.Row row = writer.newRow();
                row.putInt(0, rnd.nextInt());
                row.putShort(1, rnd.nextShort());
                row.putByte(2, rnd.nextByte());
                row.putDouble(3, rnd.nextDouble());
                row.putFloat(4, rnd.nextFloat());
                row.putLong(5, rnd.nextLong());
                row.putSym(6, rnd.nextChars(10));
                row.putBool(7, rnd.nextBoolean());
                row.putDate(8, rnd.nextLong());
                row.putTimestamp(9, rnd.nextLong());
                row.append();
            }
            writer.commit();
        }

        try (TableReader reader = new TableReader(configuration, "all")) {
            final SymbolAsIntTypes valueTypes = new SymbolAsIntTypes().of(reader.getMetadata());
            try (final Map map = new FastMap(Numbers.SIZE_1MB, keyTypes, valueTypes, N, 0.5, 100)) {

                EntityColumnFilter columnFilter = new EntityColumnFilter();
                columnFilter.of(reader.getMetadata().getColumnCount());
                RecordValueSink sink = RecordValueSinkFactory.getInstance(new BytecodeAssembler(), reader.getMetadata(), columnFilter);
                RecordCursor cursor = reader.getCursor();
                final Record record = cursor.getRecord();

                int index = 0;
                while (cursor.hasNext()) {
                    MapKey key = map.withKey();
                    key.putInt(index++);
                    MapValue value = key.createValue();
                    sink.copy(record, value);
                }

                Assert.assertEquals(N, index);

                rnd.reset();

                StaticSymbolTable symbolTable = reader.getSymbolMapReader(6);

                for (int i = 0; i < N; i++) {
                    MapKey key = map.withKey();
                    key.putInt(i);
                    MapValue value = key.findValue();

                    Assert.assertNotNull(value);
                    Assert.assertEquals(rnd.nextInt(), value.getInt(0));
                    Assert.assertEquals(rnd.nextShort(), value.getShort(1));
                    Assert.assertEquals(rnd.nextByte(), value.getByte(2));
                    Assert.assertEquals(rnd.nextDouble(), value.getDouble(3), 0.000001);
                    Assert.assertEquals(rnd.nextFloat(), value.getFloat(4), 0.000001f);
                    Assert.assertEquals(rnd.nextLong(), value.getLong(5));
                    Assert.assertEquals(symbolTable.keyOf(rnd.nextChars(10)), value.getInt(6));
                    Assert.assertEquals(rnd.nextBoolean(), value.getBool(7));
                    Assert.assertEquals(rnd.nextLong(), value.getDate(8));
                    Assert.assertEquals(rnd.nextLong(), value.getTimestamp(9));
                }
            }
        }
    }

    @Test
    public void testSubset() {
        SingleColumnType keyTypes = new SingleColumnType(ColumnType.INT);
        try (TableModel model = new TableModel(configuration, "all", PartitionBy.NONE)
                .col("int", ColumnType.INT)
                .col("short", ColumnType.SHORT)
                .col("byte", ColumnType.BYTE)
                .col("double", ColumnType.DOUBLE)
                .col("float", ColumnType.FLOAT)
                .col("long", ColumnType.LONG)
                .col("sym", ColumnType.SYMBOL).symbolCapacity(64)
                .col("bool", ColumnType.BOOLEAN)
                .col("date", ColumnType.DATE)
                .col("ts", ColumnType.TIMESTAMP)
        ) {
            CairoTestUtils.create(model);
        }

        final int N = 1024;
        final Rnd rnd = new Rnd();
        try (TableWriter writer = new TableWriter(configuration, "all")) {

            for (int i = 0; i < N; i++) {
                TableWriter.Row row = writer.newRow();
                row.putInt(0, rnd.nextInt());
                row.putShort(1, rnd.nextShort());
                row.putByte(2, rnd.nextByte());
                row.putDouble(3, rnd.nextDouble());
                row.putFloat(4, rnd.nextFloat());
                row.putLong(5, rnd.nextLong());
                row.putSym(6, rnd.nextChars(10));
                row.putBool(7, rnd.nextBoolean());
                row.putDate(8, rnd.nextLong());
                row.putTimestamp(9, rnd.nextLong());
                row.append();
            }
            writer.commit();
        }

        try (TableReader reader = new TableReader(configuration, "all")) {
            ArrayColumnTypes valueTypes = new ArrayColumnTypes();
            valueTypes.add(ColumnType.BOOLEAN);
            valueTypes.add(ColumnType.TIMESTAMP);
            valueTypes.add(ColumnType.INT);
            try (final Map map = new FastMap(Numbers.SIZE_1MB, keyTypes, valueTypes, N, 0.5, 100)) {

                ListColumnFilter columnFilter = new ListColumnFilter();
                columnFilter.add(8);
                columnFilter.add(10);
                columnFilter.add(7);


                RecordValueSink sink = RecordValueSinkFactory.getInstance(new BytecodeAssembler(), reader.getMetadata(), columnFilter);
                RecordCursor cursor = reader.getCursor();
                final Record record = cursor.getRecord();

                int index = 0;
                while (cursor.hasNext()) {
                    MapKey key = map.withKey();
                    key.putInt(index++);
                    MapValue value = key.createValue();
                    sink.copy(record, value);
                }

                Assert.assertEquals(N, index);

                rnd.reset();

                StaticSymbolTable symbolTable = reader.getSymbolMapReader(6);

                for (int i = 0; i < N; i++) {
                    MapKey key = map.withKey();
                    key.putInt(i);
                    MapValue value = key.findValue();

                    Assert.assertNotNull(value);
                    rnd.nextInt(); // 0
                    rnd.nextShort(); // 1
                    rnd.nextByte(); // 2
                    rnd.nextDouble(); // 3
                    rnd.nextFloat(); // 4
                    rnd.nextLong(); // 5
                    Assert.assertEquals(symbolTable.keyOf(rnd.nextChars(10)), value.getInt(2)); // 6
                    Assert.assertEquals(rnd.nextBoolean(), value.getBool(0)); // 7
                    rnd.nextLong(); // 8
                    Assert.assertEquals(rnd.nextLong(), value.getTimestamp(1)); // 9
                }
            }
        }
    }
}

<|start_filename|>core/src/main/java/io/questdb/griffin/engine/join/NullRecordFactory.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.griffin.engine.join;

import io.questdb.cairo.ColumnTypes;
import io.questdb.cairo.sql.Function;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.VirtualRecord;
import io.questdb.griffin.engine.functions.constants.Constants;
import io.questdb.std.ObjList;

public class NullRecordFactory {

    public static Record getInstance(ColumnTypes types) {
        final ObjList<Function> functions = new ObjList<>(types.getColumnCount());
        for (int i = 0, n = types.getColumnCount(); i < n; i++) {
            Function function = Constants.getNullConstant(types.getColumnType(i));
            assert function != null;
            functions.add(function);
        }

        return new VirtualRecord(functions);
    }
}


<|start_filename|>ui/src/js/console/console-controller.js<|end_filename|>
import $ from "jquery"

import * as qdb from "./globals"

export function setupConsoleController(bus) {
  const grid = $("#grid")
  const quickVis = $("#quick-vis")

  grid.grid(bus)
  quickVis.quickVis(bus)
}


<|start_filename|>ui/babel.config.js<|end_filename|>
const plugins = [
  [
    "@babel/plugin-transform-runtime",
    {
      corejs: 3,
      regenerator: true,
      useESModules: true,
    },
  ],
]

module.exports = {
  env: {
    development: {
      plugins: [
        [
          "styled-components",
          {
            displayName: true,
            minify: false,
            pure: true,
            ssr: false,
          },
        ],
        "@babel/plugin-transform-react-jsx-source",
        ...plugins,
      ],
    },
    production: {
      plugins: [
        [
          "styled-components",
          {
            displayName: false,
            minify: false,
            pure: true,
            ssr: false,
          },
        ],
        ...plugins,
      ],
    },
    test: {
      presets: [
        [
          "@babel/env",
          {
            shippedProposals: true,
            targets: {
              node: "current",
            },
          },
        ],
      ],
    },
  },
  plugins: [],
  presets: [
    [
      "@babel/env",
      {
        corejs: 3,
        modules: false,
        shippedProposals: true,
        useBuiltIns: "entry",
      },
    ],
    "@babel/react",
    "@babel/typescript",
  ],
}


<|start_filename|>core/src/main/java/io/questdb/griffin/engine/LimitOverflowException.java<|end_filename|>
package io.questdb.griffin.engine;

import io.questdb.cairo.CairoException;
import io.questdb.std.ThreadLocal;

public class LimitOverflowException extends CairoException {
    private static final long serialVersionUID = 1L;
    private static final ThreadLocal<LimitOverflowException> tlException = new ThreadLocal<>(LimitOverflowException::new);

    public static LimitOverflowException instance() {
        LimitOverflowException ex = tlException.get();
        ex.message.clear();
        return ex;
    }

    public static LimitOverflowException instance(long limit) {
        LimitOverflowException ex = instance();
        ex.put("limit of ").put(limit).put(" exceeded").setCacheable(true);
        return ex;
    }

}


<|start_filename|>core/src/main/c/share/vec_ts_agg.cpp<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#include "vec_agg.h"

#define MAX_VECTOR_SIZE 512

#if INSTRSET >= 10

//#define HOUR_COUNT F_AVX512(keyedHourCount)

#elif INSTRSET >= 8

//#define HOUR_COUNT F_AVX2(keyedHourCount)

#elif INSTRSET >= 5

//#define HOUR_COUNT F_SSE41(keyedHourCount)

#elif INSTRSET >= 2

//#define HOUR_COUNT F_SSE2(keyedHourCount)

#else

#endif


#if INSTRSET < 5

// Dispatchers
//ROSTI_DISPATCHER(keyedHourCount)

#define HOUR_MICROS  3600000000L
#define DAY_HOURS  24

extern "C" {



}

#endif


<|start_filename|>core/src/main/java/io/questdb/std/datetime/microtime/GenericTimestampFormat.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.std.datetime.microtime;

import io.questdb.std.IntList;
import io.questdb.std.Numbers;
import io.questdb.std.NumericException;
import io.questdb.std.ObjList;
import io.questdb.std.datetime.AbstractDateFormat;
import io.questdb.std.datetime.DateLocale;
import io.questdb.std.str.CharSink;

public class GenericTimestampFormat extends AbstractDateFormat {
    private final IntList compiledOps;
    private final ObjList<String> delimiters;

    public GenericTimestampFormat(IntList compiledOps, ObjList<String> delimiters) {
        this.compiledOps = compiledOps;
        this.delimiters = delimiters;
    }

    @Override
    public void format(long micros, DateLocale locale, CharSequence timeZoneName, CharSink sink) {
        int day = -1;
        int month = -1;
        int year = Integer.MIN_VALUE;
        int hour = -1;
        int minute = -1;
        int second = -1;
        int dayOfWeek = -1;
        boolean leap = false;
        int millis = -1;
        int micros0 = -1;

        for (int i = 0, n = compiledOps.size(); i < n; i++) {
            int op = compiledOps.getQuick(i);
            switch (op) {

                // AM/PM
                case TimestampFormatCompiler.OP_AM_PM:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.appendAmPm(sink, hour, locale);
                    break;

                // MICROS
                case TimestampFormatCompiler.OP_MICROS_ONE_DIGIT:
                case TimestampFormatCompiler.OP_MICROS_GREEDY:
                    if (micros0 == -1) {
                        micros0 = Timestamps.getMicrosOfSecond(micros);
                    }
                    sink.put(micros0);
                    break;

                case TimestampFormatCompiler.OP_MICROS_THREE_DIGITS:
                    if (micros0 == -1) {
                        micros0 = Timestamps.getMicrosOfSecond(micros);
                    }
                    TimestampFormatUtils.append00(sink, micros0);
                    break;

                // MILLIS
                case TimestampFormatCompiler.OP_MILLIS_ONE_DIGIT:
                case TimestampFormatCompiler.OP_MILLIS_GREEDY:
                    if (millis == -1) {
                        millis = Timestamps.getMillisOfSecond(micros);
                    }
                    sink.put(millis);
                    break;

                case TimestampFormatCompiler.OP_MILLIS_THREE_DIGITS:
                    if (millis == -1) {
                        millis = Timestamps.getMillisOfSecond(micros);
                    }
                    TimestampFormatUtils.append00(sink, millis);
                    break;

                // NANOS
                case TimestampFormatCompiler.OP_NANOS_ONE_DIGIT:
                case TimestampFormatCompiler.OP_NANOS_GREEDY:
                    sink.put(0);
                    break;

                case TimestampFormatCompiler.OP_NANOS_THREE_DIGITS:
                    TimestampFormatUtils.append00(sink, 0);
                    break;

                // SECOND
                case TimestampFormatCompiler.OP_SECOND_ONE_DIGIT:
                case TimestampFormatCompiler.OP_SECOND_GREEDY:
                    if (second == -1) {
                        second = Timestamps.getSecondOfMinute(micros);
                    }
                    sink.put(second);
                    break;

                case TimestampFormatCompiler.OP_SECOND_TWO_DIGITS:
                    if (second == -1) {
                        second = Timestamps.getSecondOfMinute(micros);
                    }
                    TimestampFormatUtils.append0(sink, second);
                    break;


                // MINUTE
                case TimestampFormatCompiler.OP_MINUTE_ONE_DIGIT:
                case TimestampFormatCompiler.OP_MINUTE_GREEDY:
                    if (minute == -1) {
                        minute = Timestamps.getMinuteOfHour(micros);
                    }
                    sink.put(minute);
                    break;

                case TimestampFormatCompiler.OP_MINUTE_TWO_DIGITS:
                    if (minute == -1) {
                        minute = Timestamps.getMinuteOfHour(micros);
                    }
                    TimestampFormatUtils.append0(sink, minute);
                    break;


                // HOUR (0-11)
                case TimestampFormatCompiler.OP_HOUR_12_ONE_DIGIT:
                case TimestampFormatCompiler.OP_HOUR_12_GREEDY:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.appendHour12(sink, hour);
                    break;

                case TimestampFormatCompiler.OP_HOUR_12_TWO_DIGITS:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.appendHour12Padded(sink, hour);
                    break;

                // HOUR (1-12)
                case TimestampFormatCompiler.OP_HOUR_12_ONE_DIGIT_ONE_BASED:
                case TimestampFormatCompiler.OP_HOUR_12_GREEDY_ONE_BASED:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.appendHour121(sink, hour);
                    break;

                case TimestampFormatCompiler.OP_HOUR_12_TWO_DIGITS_ONE_BASED:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.appendHour121Padded(sink, hour);
                    break;

                // HOUR (0-23)
                case TimestampFormatCompiler.OP_HOUR_24_ONE_DIGIT:
                case TimestampFormatCompiler.OP_HOUR_24_GREEDY:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    sink.put(hour);
                    break;

                case TimestampFormatCompiler.OP_HOUR_24_TWO_DIGITS:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.append0(sink, hour);
                    break;

                // HOUR (1 - 24)
                case TimestampFormatCompiler.OP_HOUR_24_ONE_DIGIT_ONE_BASED:
                case TimestampFormatCompiler.OP_HOUR_24_GREEDY_ONE_BASED:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    sink.put(hour + 1);
                    break;

                case TimestampFormatCompiler.OP_HOUR_24_TWO_DIGITS_ONE_BASED:
                    if (hour == -1) {
                        hour = Timestamps.getHourOfDay(micros);
                    }
                    TimestampFormatUtils.append0(sink, hour + 1);
                    break;

                // DAY
                case TimestampFormatCompiler.OP_DAY_ONE_DIGIT:
                case TimestampFormatCompiler.OP_DAY_GREEDY:
                    if (day == -1) {
                        if (year == Integer.MIN_VALUE) {
                            year = Timestamps.getYear(micros);
                            leap = Timestamps.isLeapYear(year);
                        }

                        if (month == -1) {
                            month = Timestamps.getMonthOfYear(micros, year, leap);
                        }

                        day = Timestamps.getDayOfMonth(micros, year, month, leap);
                    }
                    sink.put(day);
                    break;
                case TimestampFormatCompiler.OP_DAY_TWO_DIGITS:
                    if (day == -1) {
                        if (year == Integer.MIN_VALUE) {
                            year = Timestamps.getYear(micros);
                            leap = Timestamps.isLeapYear(year);
                        }

                        if (month == -1) {
                            month = Timestamps.getMonthOfYear(micros, year, leap);
                        }

                        day = Timestamps.getDayOfMonth(micros, year, month, leap);
                    }
                    TimestampFormatUtils.append0(sink, day);
                    break;

                case TimestampFormatCompiler.OP_DAY_NAME_LONG:
                    if (dayOfWeek == -1) {
                        dayOfWeek = Timestamps.getDayOfWeekSundayFirst(micros);
                    }
                    sink.put(locale.getWeekday(dayOfWeek));
                    break;

                case TimestampFormatCompiler.OP_DAY_NAME_SHORT:
                    if (dayOfWeek == -1) {
                        dayOfWeek = Timestamps.getDayOfWeekSundayFirst(micros);
                    }
                    sink.put(locale.getShortWeekday(dayOfWeek));
                    break;

                case TimestampFormatCompiler.OP_DAY_OF_WEEK:
                    if (dayOfWeek == -1) {
                        dayOfWeek = Timestamps.getDayOfWeekSundayFirst(micros);
                    }
                    sink.put(dayOfWeek);
                    break;

                // MONTH

                case TimestampFormatCompiler.OP_MONTH_ONE_DIGIT:
                case TimestampFormatCompiler.OP_MONTH_GREEDY:
                    if (month == -1) {
                        if (year == Integer.MIN_VALUE) {
                            year = Timestamps.getYear(micros);
                            leap = Timestamps.isLeapYear(year);
                        }

                        month = Timestamps.getMonthOfYear(micros, year, leap);
                    }
                    sink.put(month);
                    break;
                case TimestampFormatCompiler.OP_MONTH_TWO_DIGITS:
                    if (month == -1) {
                        if (year == Integer.MIN_VALUE) {
                            year = Timestamps.getYear(micros);
                            leap = Timestamps.isLeapYear(year);
                        }

                        month = Timestamps.getMonthOfYear(micros, year, leap);
                    }
                    TimestampFormatUtils.append0(sink, month);
                    break;

                case TimestampFormatCompiler.OP_MONTH_SHORT_NAME:
                    if (month == -1) {
                        if (year == Integer.MIN_VALUE) {
                            year = Timestamps.getYear(micros);
                            leap = Timestamps.isLeapYear(year);
                        }

                        month = Timestamps.getMonthOfYear(micros, year, leap);
                    }
                    sink.put(locale.getShortMonth(month - 1));
                    break;
                case TimestampFormatCompiler.OP_MONTH_LONG_NAME:
                    if (month == -1) {
                        if (year == Integer.MIN_VALUE) {
                            year = Timestamps.getYear(micros);
                            leap = Timestamps.isLeapYear(year);
                        }

                        month = Timestamps.getMonthOfYear(micros, year, leap);
                    }
                    sink.put(locale.getMonth(month - 1));
                    break;

                // YEAR

                case TimestampFormatCompiler.OP_YEAR_ONE_DIGIT:
                case TimestampFormatCompiler.OP_YEAR_GREEDY:
                    if (year == Integer.MIN_VALUE) {
                        year = Timestamps.getYear(micros);
                        leap = Timestamps.isLeapYear(year);
                    }
                    sink.put(year);
                    break;
                case TimestampFormatCompiler.OP_YEAR_TWO_DIGITS:
                    if (year == Integer.MIN_VALUE) {
                        year = Timestamps.getYear(micros);
                        leap = Timestamps.isLeapYear(year);
                    }
                    TimestampFormatUtils.append0(sink, year % 100);
                    break;
                case TimestampFormatCompiler.OP_YEAR_FOUR_DIGITS:
                    if (year == Integer.MIN_VALUE) {
                        year = Timestamps.getYear(micros);
                        leap = Timestamps.isLeapYear(year);
                    }
                    TimestampFormatUtils.append000(sink, year);
                    break;

                // ERA
                case TimestampFormatCompiler.OP_ERA:
                    if (year == Integer.MIN_VALUE) {
                        year = Timestamps.getYear(micros);
                        leap = Timestamps.isLeapYear(year);
                    }
                    TimestampFormatUtils.appendEra(sink, year, locale);
                    break;

                // TIMEZONE
                case TimestampFormatCompiler.OP_TIME_ZONE_SHORT:
                case TimestampFormatCompiler.OP_TIME_ZONE_GMT_BASED:
                case TimestampFormatCompiler.OP_TIME_ZONE_ISO_8601_1:
                case TimestampFormatCompiler.OP_TIME_ZONE_ISO_8601_2:
                case TimestampFormatCompiler.OP_TIME_ZONE_ISO_8601_3:
                case TimestampFormatCompiler.OP_TIME_ZONE_LONG:
                case TimestampFormatCompiler.OP_TIME_ZONE_RFC_822:
                    sink.put(timeZoneName);
                    break;

                // SEPARATORS
                default:
                    sink.put(delimiters.getQuick(-op - 1));
                    break;
            }
        }
    }

    @Override
    public long parse(CharSequence in, int lo, int hi, DateLocale locale) throws NumericException {
        int day = 1;
        int month = 1;
        int year = 1970;
        int hour = 0;
        int minute = 0;
        int second = 0;
        int millis = 0;
        int micros = 0;
        int era = 1;
        int timezone = -1;
        long offset = Long.MIN_VALUE;
        int hourType = TimestampFormatUtils.HOUR_24;
        int pos = lo;
        long l;
        int len;

        for (int i = 0, n = compiledOps.size(); i < n; i++) {
            int op = compiledOps.getQuick(i);
            switch (op) {

                // AM/PM
                case TimestampFormatCompiler.OP_AM_PM:
                    l = locale.matchAMPM(in, pos, hi);
                    hourType = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // MICROS
                case TimestampFormatCompiler.OP_MICROS_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    micros = Numbers.parseInt(in, pos, ++pos);
                    break;

                case TimestampFormatCompiler.OP_MICROS_THREE_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 2, hi);
                    micros = Numbers.parseInt(in, pos, pos += 3);
                    break;

                case TimestampFormatCompiler.OP_MICROS_GREEDY:
                    l = Numbers.parseInt000Greedy(in, pos, hi);
                    micros = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // NANOS - ignoring parsed values
                case TimestampFormatCompiler.OP_NANOS_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos++, hi);
                    break;

                case TimestampFormatCompiler.OP_NANOS_THREE_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 2, hi);
                    pos += 3;
                    break;

                case TimestampFormatCompiler.OP_NANOS_GREEDY:
                    pos += Numbers.decodeHighInt(Numbers.parseIntSafely(in, pos, hi));
                    break;

                // MILLIS
                case TimestampFormatCompiler.OP_MILLIS_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    millis = Numbers.parseInt(in, pos, ++pos);
                    break;

                case TimestampFormatCompiler.OP_MILLIS_THREE_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 2, hi);
                    millis = Numbers.parseInt(in, pos, pos += 3);
                    break;

                case TimestampFormatCompiler.OP_MILLIS_GREEDY:
                    l = Numbers.parseInt000Greedy(in, pos, hi);
                    millis = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // SECOND
                case TimestampFormatCompiler.OP_SECOND_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    second = Numbers.parseInt(in, pos, ++pos);
                    break;

                case TimestampFormatCompiler.OP_SECOND_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    second = Numbers.parseInt(in, pos, pos += 2);
                    break;

                case TimestampFormatCompiler.OP_SECOND_GREEDY:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    second = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // MINUTE
                case TimestampFormatCompiler.OP_MINUTE_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    minute = Numbers.parseInt(in, pos, ++pos);
                    break;

                case TimestampFormatCompiler.OP_MINUTE_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    minute = Numbers.parseInt(in, pos, pos += 2);
                    break;

                case TimestampFormatCompiler.OP_MINUTE_GREEDY:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    minute = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // HOUR (0-11)
                case TimestampFormatCompiler.OP_HOUR_12_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    hour = Numbers.parseInt(in, pos, ++pos);
                    if (hourType == TimestampFormatUtils.HOUR_24) {
                        hourType = TimestampFormatUtils.HOUR_AM;
                    }
                    break;

                case TimestampFormatCompiler.OP_HOUR_12_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    hour = Numbers.parseInt(in, pos, pos += 2);
                    if (hourType == TimestampFormatUtils.HOUR_24) {
                        hourType = TimestampFormatUtils.HOUR_AM;
                    }
                    break;

                case TimestampFormatCompiler.OP_HOUR_12_GREEDY:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    hour = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    if (hourType == TimestampFormatUtils.HOUR_24) {
                        hourType = TimestampFormatUtils.HOUR_AM;
                    }
                    break;

                // HOUR (1-12)
                case TimestampFormatCompiler.OP_HOUR_12_ONE_DIGIT_ONE_BASED:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    hour = Numbers.parseInt(in, pos, ++pos) - 1;
                    if (hourType == TimestampFormatUtils.HOUR_24) {
                        hourType = TimestampFormatUtils.HOUR_AM;
                    }
                    break;

                case TimestampFormatCompiler.OP_HOUR_12_TWO_DIGITS_ONE_BASED:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    hour = Numbers.parseInt(in, pos, pos += 2) - 1;
                    if (hourType == TimestampFormatUtils.HOUR_24) {
                        hourType = TimestampFormatUtils.HOUR_AM;
                    }
                    break;

                case TimestampFormatCompiler.OP_HOUR_12_GREEDY_ONE_BASED:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    hour = Numbers.decodeLowInt(l) - 1;
                    pos += Numbers.decodeHighInt(l);
                    if (hourType == TimestampFormatUtils.HOUR_24) {
                        hourType = TimestampFormatUtils.HOUR_AM;
                    }
                    break;

                // HOUR (0-23)
                case TimestampFormatCompiler.OP_HOUR_24_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    hour = Numbers.parseInt(in, pos, ++pos);
                    break;

                case TimestampFormatCompiler.OP_HOUR_24_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    hour = Numbers.parseInt(in, pos, pos += 2);
                    break;

                case TimestampFormatCompiler.OP_HOUR_24_GREEDY:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    hour = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // HOUR (1 - 24)
                case TimestampFormatCompiler.OP_HOUR_24_ONE_DIGIT_ONE_BASED:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    hour = Numbers.parseInt(in, pos, ++pos) - 1;
                    break;

                case TimestampFormatCompiler.OP_HOUR_24_TWO_DIGITS_ONE_BASED:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    hour = Numbers.parseInt(in, pos, pos += 2) - 1;
                    break;

                case TimestampFormatCompiler.OP_HOUR_24_GREEDY_ONE_BASED:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    hour = Numbers.decodeLowInt(l) - 1;
                    pos += Numbers.decodeHighInt(l);
                    break;

                // DAY
                case TimestampFormatCompiler.OP_DAY_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    day = Numbers.parseInt(in, pos, ++pos);
                    break;
                case TimestampFormatCompiler.OP_DAY_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    day = Numbers.parseInt(in, pos, pos += 2);
                    break;
                case TimestampFormatCompiler.OP_DAY_GREEDY:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    day = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                case TimestampFormatCompiler.OP_DAY_NAME_LONG:
                case TimestampFormatCompiler.OP_DAY_NAME_SHORT:
                    l = locale.matchWeekday(in, pos, hi);
                    // ignore weekday
                    pos += Numbers.decodeHighInt(l);
                    break;

                case TimestampFormatCompiler.OP_DAY_OF_WEEK:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    // ignore weekday
                    Numbers.parseInt(in, pos, ++pos);
                    break;

                // MONTH

                case TimestampFormatCompiler.OP_MONTH_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    month = Numbers.parseInt(in, pos, ++pos);
                    break;
                case TimestampFormatCompiler.OP_MONTH_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    month = Numbers.parseInt(in, pos, pos += 2);
                    break;
                case TimestampFormatCompiler.OP_MONTH_GREEDY:
                    l = Numbers.parseIntSafely(in, pos, hi);
                    month = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                case TimestampFormatCompiler.OP_MONTH_SHORT_NAME:
                case TimestampFormatCompiler.OP_MONTH_LONG_NAME:
                    l = locale.matchMonth(in, pos, hi);
                    month = Numbers.decodeLowInt(l) + 1;
                    pos += Numbers.decodeHighInt(l);
                    break;

                // YEAR

                case TimestampFormatCompiler.OP_YEAR_ONE_DIGIT:
                    TimestampFormatUtils.assertRemaining(pos, hi);
                    year = Numbers.parseInt(in, pos, ++pos);
                    break;
                case TimestampFormatCompiler.OP_YEAR_TWO_DIGITS:
                    TimestampFormatUtils.assertRemaining(pos + 1, hi);
                    year = TimestampFormatUtils.adjustYear(Numbers.parseInt(in, pos, pos += 2));
                    break;
                case TimestampFormatCompiler.OP_YEAR_FOUR_DIGITS:
                    if (pos < hi && in.charAt(pos) == '-') {
                        TimestampFormatUtils.assertRemaining(pos + 4, hi);
                        year = -Numbers.parseInt(in, pos + 1, pos += 5);
                    } else {
                        TimestampFormatUtils.assertRemaining(pos + 3, hi);
                        year = Numbers.parseInt(in, pos, pos += 4);
                    }
                    break;
                case TimestampFormatCompiler.OP_YEAR_GREEDY:
                    l = TimestampFormatUtils.parseYearGreedy(in, pos, hi);
                    year = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // ERA
                case TimestampFormatCompiler.OP_ERA:
                    l = locale.matchEra(in, pos, hi);
                    era = Numbers.decodeLowInt(l);
                    pos += Numbers.decodeHighInt(l);
                    break;

                // TIMEZONE
                case TimestampFormatCompiler.OP_TIME_ZONE_SHORT:
                case TimestampFormatCompiler.OP_TIME_ZONE_GMT_BASED:
                case TimestampFormatCompiler.OP_TIME_ZONE_ISO_8601_1:
                case TimestampFormatCompiler.OP_TIME_ZONE_ISO_8601_2:
                case TimestampFormatCompiler.OP_TIME_ZONE_ISO_8601_3:
                case TimestampFormatCompiler.OP_TIME_ZONE_LONG:
                case TimestampFormatCompiler.OP_TIME_ZONE_RFC_822:

                    l = Timestamps.parseOffset(in, pos, hi);
                    if (l == Long.MIN_VALUE) {
                        l = locale.matchZone(in, pos, hi);
                        timezone = Numbers.decodeLowInt(l);
                    } else {
                        offset = Numbers.decodeLowInt(l) * Timestamps.MINUTE_MICROS;
                    }
                    pos += Numbers.decodeHighInt(l);
                    break;

                // SEPARATORS
                default:
                    String delimiter = delimiters.getQuick(-op - 1);
                    len = delimiter.length();
                    if (len == 1) {
                        TimestampFormatUtils.assertChar(delimiter.charAt(0), in, pos++, hi);
                    } else {
                        pos = TimestampFormatUtils.assertString(delimiter, len, in, pos, hi);
                    }
                    break;
            }
        }

        TimestampFormatUtils.assertNoTail(pos, hi);

        return TimestampFormatUtils.compute(locale, era, year, month, day, hour, minute, second, millis, micros, timezone, offset, hourType);
    }
}


<|start_filename|>core/src/main/java/io/questdb/Telemetry.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb;

public final class Telemetry {

    // These event types are in addition to those declared in
    // io.questdb.griffin.CompiledQuery. We use them to identify start/stop events of the server

    public static final short SYSTEM_EVENT_UP = 100;
    public static final short SYSTEM_EVENT_DOWN = 101;
    public static final short SYSTEM_ILP_RESERVE_WRITER = 102;

    public static final short ORIGIN_INTERNAL = 1;
    public static final short ORIGIN_HTTP_JSON = 2;
    public static final short ORIGIN_POSTGRES = 3;
    public static final short ORIGIN_HTTP_TEXT = 4;
    public static final short ORIGIN_ILP_TCP = 5;
}


<|start_filename|>core/src/main/java/io/questdb/cutlass/http/processors/StaticContentProcessor.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.cutlass.http.processors;

import io.questdb.cutlass.http.*;
import io.questdb.log.Log;
import io.questdb.log.LogFactory;
import io.questdb.log.LogRecord;
import io.questdb.network.PeerDisconnectedException;
import io.questdb.network.PeerIsSlowToReadException;
import io.questdb.std.*;
import io.questdb.std.str.FileNameExtractorCharSequence;
import io.questdb.std.str.LPSZ;
import io.questdb.std.str.PrefixedPath;

import java.io.Closeable;

public class StaticContentProcessor implements HttpRequestProcessor, Closeable {
    private static final Log LOG = LogFactory.getLog(StaticContentProcessor.class);
    private static final LocalValue<StaticContentProcessorState> LV = new LocalValue<>();
    private final MimeTypesCache mimeTypes;
    private final HttpRangeParser rangeParser = new HttpRangeParser();
    private final PrefixedPath prefixedPath;
    private final CharSequence indexFileName;
    private final FilesFacade ff;
    private final String keepAliveHeader;
    private final String httpProtocolVersion;

    public StaticContentProcessor(HttpServerConfiguration configuration) {
        this.mimeTypes = configuration.getStaticContentProcessorConfiguration().getMimeTypesCache();
        this.prefixedPath = new PrefixedPath(configuration.getStaticContentProcessorConfiguration().getPublicDirectory());
        this.indexFileName = configuration.getStaticContentProcessorConfiguration().getIndexFileName();
        this.ff = configuration.getStaticContentProcessorConfiguration().getFilesFacade();
        this.keepAliveHeader = configuration.getStaticContentProcessorConfiguration().getKeepAliveHeader();
        this.httpProtocolVersion = configuration.getHttpContextConfiguration().getHttpVersion();
    }

    private static void sendStatusWithDefaultMessage(HttpConnectionContext context, int code) throws PeerDisconnectedException, PeerIsSlowToReadException {
        context.simpleResponse().sendStatusWithDefaultMessage(code);
    }

    @Override
    public void close() {
        Misc.free(prefixedPath);
    }

    public LogRecord logInfoWithFd(HttpConnectionContext context) {
        return LOG.info().$('[').$(context.getFd()).$("] ");
    }

    @Override
    public void onRequestComplete(HttpConnectionContext context) throws PeerDisconnectedException, PeerIsSlowToReadException {
        final HttpRequestHeader headers = context.getRequestHeader();
        CharSequence url = headers.getUrl();
        logInfoWithFd(context).$("incoming [url=").$(url).$(']').$();
        if (Chars.contains(url, "..")) {
            logInfoWithFd(context).$("URL abuse: ").$(url).$();
            sendStatusWithDefaultMessage(context, 404);
        } else {
            PrefixedPath path = prefixedPath.rewind();

            if (Chars.equals(url, '/')) {
                path.concat(indexFileName);
            } else {
                path.concat(url);
            }

            path.$();

            if (ff.exists(path)) {
                send(context, path, headers.getUrlParam("attachment") != null);
            } else {
                logInfoWithFd(context).$("not found [path=").$(path).$(']').$();
                sendStatusWithDefaultMessage(context, 404);
            }
        }
    }

    @Override
    public void resumeSend(HttpConnectionContext context) throws PeerDisconnectedException, PeerIsSlowToReadException {
        LOG.debug().$("resumeSend").$();
        StaticContentProcessorState state = LV.get(context);

        if (state == null || state.fd == -1) {
            return;
        }

        final HttpRawSocket socket = context.getRawResponseSocket();
        long address = socket.getBufferAddress();
        int size = socket.getBufferSize();

        long l;
        // todo: check what happens when this code cannot read file
        while (state.bytesSent < state.sendMax && (l = ff.read(state.fd, address, size, state.bytesSent)) > 0) {
            if (l + state.bytesSent > state.sendMax) {
                l = state.sendMax - state.bytesSent;
            }
            state.bytesSent += l;
            socket.send((int) l);
        }
    }

    private void send(HttpConnectionContext context, LPSZ path, boolean asAttachment) throws PeerDisconnectedException, PeerIsSlowToReadException {
        int n = Chars.lastIndexOf(path, '.');
        if (n == -1) {
            logInfoWithFd(context).$("missing extension [file=").$(path).$(']').$();
            sendStatusWithDefaultMessage(context, 404);
            return;
        }

        HttpRequestHeader headers = context.getRequestHeader();
        CharSequence contentType = mimeTypes.valueAt(mimeTypes.keyIndex(path, n + 1, path.length()));
        CharSequence val;
        if ((val = headers.getHeader("Range")) != null) {
            sendRange(context, val, path, contentType, asAttachment);
            return;
        }

        int l;
        // attempt not to send file when remote side already has
        // up-to-date version of the same
        if ((val = headers.getHeader("If-None-Match")) != null
                && (l = val.length()) > 2
                && val.charAt(0) == '"'
                && val.charAt(l - 1) == '"') {
            try {
                long that = Numbers.parseLong(val, 1, l - 1);
                if (that == ff.getLastModified(path)) {
                    context.simpleResponse().sendStatus(304);
                    return;
                }
            } catch (NumericException e) {
                LOG.info().$("bad 'If-None-Match' [value=").$(val).$(']').$();
                sendStatusWithDefaultMessage(context, 400);
                return;
            }
        }

        sendVanilla(context, path, contentType, asAttachment);
    }

    private void sendRange(
            HttpConnectionContext context,
            CharSequence range,
            LPSZ path,
            CharSequence contentType,
            boolean asAttachment) throws PeerDisconnectedException, PeerIsSlowToReadException {
        if (rangeParser.of(range)) {

            StaticContentProcessorState state = LV.get(context);
            if (state == null) {
                LV.set(context, state = new StaticContentProcessorState());
            }

            state.fd = ff.openRO(path);
            if (state.fd == -1) {
                LOG.info().$("Cannot open file: ").$(path).$();
                sendStatusWithDefaultMessage(context, 404);
                return;
            }

            state.bytesSent = 0;

            final long length = ff.length(path);
            final long lo = rangeParser.getLo();
            final long hi = rangeParser.getHi();
            if (lo > length || (hi != Long.MAX_VALUE && hi > length) || lo > hi) {
                sendStatusWithDefaultMessage(context, 416);
            } else {
                state.bytesSent = lo;
                state.sendMax = hi == Long.MAX_VALUE ? length : hi;

                final HttpResponseHeader header = context.getResponseHeader();
                header.status(httpProtocolVersion, 206, contentType, state.sendMax - lo);
                if (asAttachment) {
                    header.put("Content-Disposition: attachment; filename=\"").put(FileNameExtractorCharSequence.get(path)).put('\"').put(Misc.EOL);
                }
                header.put("Accept-Ranges: bytes").put(Misc.EOL);
                header.put("Content-Range: bytes ").put(lo).put('-').put(state.sendMax).put('/').put(length).put(Misc.EOL);
                header.put("ETag: ").put(ff.getLastModified(path)).put(Misc.EOL);
                if (keepAliveHeader != null) {
                    header.put(keepAliveHeader);
                }
                header.send();
                resumeSend(context);
            }
        } else {
            sendStatusWithDefaultMessage(context, 416);
        }
    }

    private void sendVanilla(
            HttpConnectionContext context,
            LPSZ path, CharSequence contentType,
            boolean asAttachment
    ) throws PeerDisconnectedException, PeerIsSlowToReadException {
        long fd = ff.openRO(path);
        if (fd == -1) {
            LOG.info().$("Cannot open file: ").$(path).$('(').$(ff.errno()).$(')').$();
            sendStatusWithDefaultMessage(context, 404);
        } else {
            StaticContentProcessorState h = LV.get(context);
            if (h == null) {
                LV.set(context, h = new StaticContentProcessorState());
            }
            h.fd = fd;
            h.bytesSent = 0;
            final long length = ff.length(path);
            h.sendMax = length;

            final HttpResponseHeader header = context.getResponseHeader();
            header.status(httpProtocolVersion, 200, contentType, length);
            if (asAttachment) {
                header.put("Content-Disposition: attachment; filename=\"").put(FileNameExtractorCharSequence.get(path)).put("\"").put(Misc.EOL);
            }
            header.put("ETag: ").put('"').put(ff.getLastModified(path)).put('"').put(Misc.EOL);
            header.setKeepAlive(keepAliveHeader);
            header.send();
            resumeSend(context);
        }
    }

}


<|start_filename|>core/src/main/java/io/questdb/std/datetime/TimeZoneRuleFactory.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.std.datetime;

import io.questdb.std.CharSequenceIntHashMap;
import io.questdb.std.Numbers;
import io.questdb.std.ObjList;
import io.questdb.std.datetime.microtime.TimeZoneRulesMicros;
import io.questdb.std.datetime.microtime.Timestamps;
import io.questdb.std.datetime.millitime.Dates;
import io.questdb.std.datetime.millitime.TimeZoneRulesMillis;

import java.time.ZoneId;
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesProvider;
import java.util.Map;

public class TimeZoneRuleFactory {

    public static final int RESOLUTION_MILLIS = 0;
    public static final int RESOLUTION_MICROS = 1;

    public static final TimeZoneRuleFactory INSTANCE = new TimeZoneRuleFactory();

    private final CharSequenceIntHashMap ruleMap = new CharSequenceIntHashMap();
    private final ObjList<TimeZoneRules> ruleList = new ObjList<>();

    public TimeZoneRuleFactory() {
        int index = 0;
        for (String z : ZoneRulesProvider.getAvailableZoneIds()) {
            final ZoneRules rules = ZoneRulesProvider.getRules(z, true);
            ruleList.add(new TimeZoneRulesMillis(rules));
            ruleList.add(new TimeZoneRulesMicros(rules));
            ruleMap.put(z, index++);
        }

        for (Map.Entry<String, String> e : ZoneId.SHORT_IDS.entrySet()) {
            String key = e.getKey();
            String alias = e.getValue();

            // key already added somehow?
            int i = ruleMap.get(key);
            if (i == -1) {
                // no, good, add
                i = ruleMap.get(alias);
                if (i == -1) {
                    // this could be fixed offset, try parsing value as one
                    long offset = Dates.parseOffset(alias, 0, alias.length());
                    if (offset != Long.MIN_VALUE) {
                        ruleList.add(new FixedTimeZoneRule(Numbers.decodeLowInt(offset) * Dates.MINUTE_MILLIS));
                        ruleList.add(new FixedTimeZoneRule(Numbers.decodeLowInt(offset) * Timestamps.MINUTE_MICROS));
                        ruleMap.put(key, index++);
                    }
                } else {
                    ruleMap.put(key, i);
                }
            }
        }
    }

    public int getTimeZoneRulesIndex(CharSequence id) {
        return ruleMap.get(id);
    }

    public TimeZoneRules getTimeZoneRulesQuick(int index, int resolution) {
        return ruleList.getQuick(2 * index + resolution);
    }
}


<|start_filename|>core/src/main/java/io/questdb/griffin/PostOrderTreeTraversalAlgo.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.griffin;

import io.questdb.griffin.model.ExpressionNode;
import io.questdb.std.IntStack;

import java.util.ArrayDeque;

final public class PostOrderTreeTraversalAlgo {
    private final ArrayDeque<ExpressionNode> stackBackup = new ArrayDeque<>();
    private final IntStack indexStackBackup = new IntStack();
    private final IntStack backupDepth = new IntStack();
    private final ArrayDeque<ExpressionNode> stack = new ArrayDeque<>();
    private final IntStack indexStack = new IntStack();

    public void backup() {
        int size = stack.size();
        backupDepth.push(size);
        for (int i = 0; i < size; i++) {
            stackBackup.push(stack.poll());
            indexStackBackup.push(indexStack.pop());
        }
    }

    public void restore() {
        if (backupDepth.size() > 0) {
            int size = backupDepth.pop();
            for (int i = 0; i < size; i++) {
                stack.push(stackBackup.poll());
                indexStack.push(indexStackBackup.pop());
            }
        }
    }

    public void traverse(ExpressionNode node, Visitor visitor) throws SqlException {

        backup();
        try {
            // post-order iterative tree traversal
            // see http://en.wikipedia.org/wiki/Tree_traversal

            stack.clear();
            indexStack.clear();

            ExpressionNode lastVisited = null;

            while (!stack.isEmpty() || node != null) {
                if (node != null) {
                    stack.push(node);
                    indexStack.push(0);
                    node = node.rhs;
                } else {
                    ExpressionNode peek = stack.peek();
                    assert peek != null;
                    if (peek.paramCount < 3) {
                        if (peek.lhs != null && lastVisited != peek.lhs) {
                            node = peek.lhs;
                        } else {
                            visitor.visit(peek);
                            lastVisited = stack.poll();
                            indexStack.pop();
                        }
                    } else {
                        int index = indexStack.peek();
                        if (index < peek.paramCount) {
                            node = peek.args.getQuick(index);
                            indexStack.update(index + 1);
                        } else {
                            visitor.visit(peek);
                            lastVisited = stack.poll();
                            indexStack.pop();
                        }
                    }
                }
            }
        } finally {
            restore();
        }
    }

    public interface Visitor {
        void visit(ExpressionNode node) throws SqlException;
    }
}


<|start_filename|>core/src/main/java/io/questdb/griffin/engine/orderby/SortedLightRecordCursor.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.griffin.engine.orderby;

import io.questdb.cairo.sql.DelegatingRecordCursor;
import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;
import io.questdb.cairo.sql.SymbolTable;
import io.questdb.griffin.SqlExecutionContext;
import io.questdb.griffin.SqlExecutionInterruptor;
import io.questdb.griffin.engine.RecordComparator;

class SortedLightRecordCursor implements DelegatingRecordCursor {
    private final LongTreeChain chain;
    private final RecordComparator comparator;
    private final LongTreeChain.TreeCursor chainCursor;
    private RecordCursor base;
    private Record baseRecord;

    public SortedLightRecordCursor(LongTreeChain chain, RecordComparator comparator) {
        this.chain = chain;
        this.comparator = comparator;
        // assign it once, its the same instance anyway
        this.chainCursor = chain.getCursor();
    }

    @Override
    public void close() {
        chain.clear();
        base.close();
    }

    @Override
    public long size() {
        return base.size();
    }

    @Override
    public Record getRecord() {
        return baseRecord;
    }

    @Override
    public SymbolTable getSymbolTable(int columnIndex) {
        return base.getSymbolTable(columnIndex);
    }

    @Override
    public boolean hasNext() {
        if (chainCursor.hasNext()) {
            base.recordAt(baseRecord, chainCursor.next());
            return true;
        }
        return false;
    }

    @Override
    public Record getRecordB() {
        return base.getRecordB();
    }

    @Override
    public void recordAt(Record record, long atRowId) {
        base.recordAt(record, atRowId);
    }

    @Override
    public void toTop() {
        chainCursor.toTop();
    }

    @Override
    public void of(RecordCursor base, SqlExecutionContext executionContext) {
        this.base = base;
        this.baseRecord = base.getRecord();
        final Record placeHolderRecord = base.getRecordB();
        SqlExecutionInterruptor interruptor = executionContext.getSqlExecutionInterruptor();

        chain.clear();
        while (base.hasNext()) {
            interruptor.checkInterrupted();
            // Tree chain is liable to re-position record to
            // other rows to do record comparison. We must use our
            // own record instance in case base cursor keeps
            // state in the record it returns.
            chain.put(
                    baseRecord,
                    base,
                    placeHolderRecord,
                    comparator
            );
        }
        chainCursor.toTop();
    }
}


<|start_filename|>core/src/main/java/io/questdb/cairo/map/CompactMapCursor.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.cairo.map;

import io.questdb.cairo.sql.Record;
import io.questdb.cairo.sql.RecordCursor;

public class CompactMapCursor implements RecordCursor {

    private final CompactMapRecord recordA;
    private final CompactMapRecord recordB;
    private long offsetHi;
    private long nextOffset;

    public CompactMapCursor(CompactMapRecord record) {
        this.recordA = record;
        this.recordB = record.clone();
    }

    @Override
    public void close() {
    }

    @Override
    public MapRecord getRecord() {
        return recordA;
    }

    @Override
    public boolean hasNext() {
        if (nextOffset < offsetHi) {
            recordA.of(nextOffset);
            nextOffset = recordA.getNextRecordOffset();
            return true;
        }
        return false;
    }

    @Override
    public MapRecord getRecordB() {
        return recordB;
    }

    @Override
    public void recordAt(Record record, long atRowId) {
        ((CompactMapRecord) record).of(atRowId);
    }

    @Override
    public void toTop() {
        nextOffset = 0;
    }

    void of(long offsetHi) {
        this.nextOffset = 0;
        this.offsetHi = offsetHi;
    }

    @Override
    public long size() {
        return -1;
    }
}


<|start_filename|>core/src/test/java/io/questdb/cutlass/http/HttpClientStateListener.java<|end_filename|>
package io.questdb.cutlass.http;

public interface HttpClientStateListener {
    void onClosed();

    void onReceived(int nBytes);
}


<|start_filename|>core/src/main/java/io/questdb/BuildInformationHolder.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb;

public class BuildInformationHolder implements BuildInformation {
    private final CharSequence questDbVersion;

    private final CharSequence jdkVersion;

    private final CharSequence commitHash;

    public BuildInformationHolder(final CharSequence questDbVersion,
                                  final CharSequence jdkVersion,
                                  final CharSequence commitHash) {
        this.questDbVersion = questDbVersion;
        this.jdkVersion = jdkVersion;
        this.commitHash = commitHash;
    }

    public BuildInformationHolder() {
        this.questDbVersion = "Unknown Version";
        this.jdkVersion = "Unknown Version";
        this.commitHash = "Unknown Version";
    }

    @Override
    public CharSequence getQuestDbVersion() {
        return questDbVersion;
    }

    @Override
    public CharSequence getJdkVersion() {
        return jdkVersion;
    }

    @Override
    public CharSequence getCommitHash() {
        return commitHash;
    }
}


<|start_filename|>core/src/main/java/io/questdb/std/datetime/TransitionRule.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.std.datetime;

public class TransitionRule {
    public static final int UTC = 0;
    public static final int STANDARD = 1;
    public static final int WALL = 2;
    public int offsetBefore;
    public int offsetAfter;
    public int standardOffset;
    public int dow;
    public int dom;
    public int month;
    public boolean midnightEOD;
    public int hour;
    public int minute;
    public int second;
    public int timeDef;
}


<|start_filename|>core/src/main/java/io/questdb/cutlass/http/processors/TextImportProcessorState.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.cutlass.http.processors;

import io.questdb.cairo.CairoEngine;
import io.questdb.cutlass.text.TextLoader;
import io.questdb.std.Misc;
import io.questdb.std.Mutable;

import java.io.Closeable;

class TextImportProcessorState implements Mutable, Closeable {
    public static final int STATE_OK = 0;
    //    public static final int STATE_INVALID_FORMAT = 1;
    public static final int STATE_DATA_ERROR = 2;
    public TextLoaderCompletedState completeState;
    TextLoader textLoader;
    public int columnIndex = 0;
    long hi;
    long lo;
    String stateMessage;
    boolean analysed = false;
    int messagePart = TextImportProcessor.MESSAGE_UNKNOWN;
    int responseState = TextImportProcessor.RESPONSE_PREFIX;
    boolean forceHeader = false;
    int state;
    boolean json = false;
    CharSequence errorMessage;

    TextImportProcessorState(CairoEngine engine) {
        this.textLoader = new TextLoader(engine);
    }

    @Override
    public void clear() {
        responseState = TextImportProcessor.RESPONSE_PREFIX;
        columnIndex = 0;
        messagePart = TextImportProcessor.MESSAGE_UNKNOWN;
        analysed = false;
        state = STATE_OK;
        textLoader.clear();
        errorMessage = null;
    }

    @Override
    public void close() {
        clear();
        textLoader = Misc.free(textLoader);
    }

    public void snapshotStateAndCloseWriter() {
        if (completeState == null) {
            completeState = new TextLoaderCompletedState();
        }
        completeState.copyState(textLoader);
        textLoader.closeWriter();
    }
}


<|start_filename|>core/src/test/java/io/questdb/griffin/engine/LongTreeSetTest.java<|end_filename|>
/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2020 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.griffin.engine;

import org.junit.Assert;
import org.junit.Test;

import io.questdb.griffin.engine.table.LongTreeSet;
import io.questdb.log.Log;
import io.questdb.log.LogFactory;
import io.questdb.std.LongList;
import io.questdb.std.Rnd;
import io.questdb.test.tools.TestUtils;

public class LongTreeSetTest {
    // To instantiate a logger to prevent memory leaks from being detected
    @SuppressWarnings("unused")
    private static final Log LOG = LogFactory.getLog(LongTreeSetTest.class);

    @Test
    public void testDuplicateValues() throws Exception {
        TestUtils.assertMemoryLeak(() -> {
            try (LongTreeSet set = new LongTreeSet(1024, 1)) {
                set.put(1);
                set.put(2);
                set.put(2);
                set.put(3);
                set.put(4);
                set.put(4);
                set.put(5);
                set.put(5);
                set.put(5);

                LongTreeSet.TreeCursor cursor = set.getCursor();
                LongList ll = new LongList();
                while (cursor.hasNext()) {
                    ll.add(cursor.next());
                }
                TestUtils.assertEquals("[1,2,3,4,5]", ll.toString());
            }
        });
    }

    @Test
    public void testSimple() throws Exception {
        TestUtils.assertMemoryLeak(() -> {
            try (LongTreeSet set = new LongTreeSet(1024 * 1024, 1)) {
                doTestSimple(set);
                set.clear();
                doTestSimple(set);
            }
        });
    }

    private void doTestSimple(LongTreeSet set) {
        Rnd rnd = new Rnd();
        LongList ll = new LongList();
        int n = 10000;
        for (int i = 0; i < n; i++) {
            long l = rnd.nextLong();
            set.put(l);
            ll.add(l);
        }

        ll.sort();
        int i = 0;
        LongTreeSet.TreeCursor cursor = set.getCursor();
        while (cursor.hasNext()) {
            long l = cursor.next();
            Assert.assertEquals(ll.getQuick(i++), l);
        }
        Assert.assertEquals(n, i);

        cursor.toTop();

        i = 0;
        while (cursor.hasNext()) {
            long l = cursor.next();
            Assert.assertEquals(ll.getQuick(i++), l);
        }
    }
}